#java #mysql #hibernate #jpa #composite-primary-key
#java #mysql #гибернация #jpa #составной первичный ключ
Вопрос:
У меня проблема, описанная вкратце в названии. Может кто-нибудь сказать мне, как я могу получить ту же базу данных, используя JPA?
create table ALBUM
(
IdAlbum int,
AlbumName varchar(35) not null,
UrlOfAlbum varchar(60) not null,
Primary Key(IdAlbum)
);
create table ARTIST
(
IdArtist int,
ArtistName varchar(35) not null,
Primary Key(IdArtist)
);
create table TRACK
(
IdTrack int,
IdAlbum int,
IdArtist int,
TrackName varchar(35) not null,
Primary Key(IdTrack, IdAlbum),
Foreign Key(IdAlbum) references Album(IdAlbum),
Foreign Key(IdArtist) references Artist(IdArtist)
);
Ответ №1:
Просто поместите столбцы во встроенный ключ и сохраните связь в основном классе:
@Embeddable
class TrackId
{
private Integer idAlbum;
private Integer idTrack;
// getters, setters, equals and hashCode
}
@Entity
class Track
{
@EmbeddedId
TrackId trackId;
@ManyToOne
@MapsId("idAlbum")
@JoinColumn(name = "idAlbum", referencedColumnName = "idAlbum")
private Album album = null;
....
}
Ответ №2:
Вам нужно использовать «производную идентификацию»:
@Entity
public class Album {
@Id
@Column(name = "IdAlbum")
private Integer id;
@Column(name = "AlbumName")
private String name;
...
}
@Embeddable
public class TrackID {
@Column(name = "IdTrack")
private Integer trackID;
@Column(name = "IdAlbum")
private Integer albumID; // NB: corresponds to PK type of Album
...
}
@Entity
public class Track {
@EmbeddedId
TrackID id;
@ManyToOne
@MapsId("albumID") // NB: maps 'albumID' attribute of embedded id
@JoinColumn(name = "IdAlbum", referencedColumnName = "IdAlbum")
private Album album;
...
}
Производные идентификаторы обсуждаются в спецификации JPA 2.1, раздел 2.4.1.
Ответ №3:
Вы должны определить класс composite-id с помощью @javax.persistence.Embeddable
@Embeddable
public class TrackPK {
@Column(name = "IdTrack")
private Integer trackId;
@JoinColumn(name = albumId, referencedColumnName = "IdAlbum")
private Album album;
// setters amp; getters
// you also have to implement equals and hashCode
}
С этого момента есть два пути. Вы можете использовать TrackPK
объект внутри своего Track
класса с @EmbeddedId
аннотацией (как предложил Висковский), или вы можете использовать @IdClass(TrackPK.class)
вне своего Track
вместе с @Entity
аннотацией. Вам также придется дублировать поля и параметры из TrackPK
класса в Track
, и использовать ту же реализацию equals
и hashCode
для Track
класса, и добавить @Id
аннотацию к обоим полям.
Я знаю, это звучит как много, но это просто копирование-вставка всей внутренней части TrackPK, и это превращается track.getTrackPK().getAlbum()
в track.getAlbum()
, избавляя вас даже от прямого использования этого класса TrackPK. Вы можете просто позволить JPA обработать это.