JPA,休眠,Java。复合主键,其中一个也是外键

JPA, Hibernate, Java. Composite primary key, one of them is also foreign key

我遇到了标题中简要描述的问题。谁能告诉我,如何使用 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)
);

只需将列放入嵌入键中并在主键中保持关系 class:

@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;

      ....
}

您必须使用 @javax.persistence.Embeddable

定义复合 ID class
@Embeddable
public class TrackPK {
    @Column(name = "IdTrack")
    private Integer trackId;
    @JoinColumn(name = albumId, referencedColumnName = "IdAlbum")
    private Album album;
    // setters & getters
    // you also have to implement equals and hashCode
}

从此有两条路。您可以在 Track class 中使用带有 @EmbeddedId 注释的 TrackPK 对象(如 Vyskovsky 所建议的),或者您可以在 [=13] 之外使用 @IdClass(TrackPK.class) =] 以及 @Entity 注释。您还必须在 Track 中复制 TrackPK class 中的字段和设置器,并对 [=] 使用 equalshashCode 的相同实现13=] class,并在两个字段上添加 @Id 注释。

我知道这听起来很多,但它只是复制粘贴整个 TrackPK 的内部结构,它会将 track.getTrackPK().getAlbum() 变成 track.getAlbum(),甚至让你不用使用那个 TrackPK class直接地。您可以让 JPA 处理它。

您需要使用"derived identity":

@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 节中进行了讨论。