如何使用JPA / EclipseLink与Junction Table建立多对多关系

我有2张桌子:

电影:movieID

用户:userID

这些表通过Queue表具有多对多的关系,并具有一个附加属性listOrder:

队列:movieID,userID,listOrder

我正在尝试使用EclipseLink对此进行建模,但是我遇到了“不兼容的映射”错误。 以下是我的代码示例:

@Entity @Table(name="movieinventory") public class Movie implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Integer movieID; @OneToMany(mappedBy="movie") private Set moviesInQueue; ...Getters/Setters... } @Entity @Table(name="Users") public class User implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Integer userID; @OneToMany(mappedBy="user") private Set moviesInQueue; ...Getters/Setters... } @IdClass(QueueItemPK.class) @Entity @Table(name="queue") public class QueueItem { @Id @ManyToOne @JoinColumn(name="movieID") private Movie movie; @Id @ManyToOne @JoinColumn(name="userID") private User user; @Basic private String listOrder; ...Getters/Setters... } public class QueueItemPK implements Serializable { private static final long serialVersionUID = 1L; private Movie movie; private User user; ...Getters/Setter... public int hashCode() { return (movie.getMovieID() + "|" + user.getUserID()).hashCode(); } public boolean equals(Object obj) { if (obj == this) return true; if (obj == null) return false; if (!(obj instanceof QueueItemPK)) return false; QueueItemPK pk = (QueueItemPK) obj; return pk.movie.getMovieID() == movie.getMovieID() && pk.user.getUserID() == user.getUserID(); } } 

QueueItemPK的目的是使我可以拥有movieID和userID的复合主键。 我不完全确定这是正确的做法。

这是错误: exception描述:[class Movie]和[class QueueItem]之间遇到了不兼容的映射。 这通常发生在映射的基数与其backpointer的基数不对应时。 我与User类有相同的错误(错误交替)。

当我从QueueItem中的电影和用户变量中取出@Id注释并使其他键成为主键时,它编译时没有错误。

任何建议,将不胜感激。

谢谢,BJ

首先,正如Mike Cornell所建议的那样,EmbeddedId / Class可能是更容易使用的选择。 尽管如此,要回答您的问题并更正代码:

 @IdClass(QueueItemPK.class) @Entity @Table(name="queue") public class QueueItem { @Id @ManyToOne(optional=false) @PrimaryKeyJoinColumn(name="movieID") private Movie movie; @Id @ManyToOne(optional=false) @PrimaryKeyJoinColumn(name="userID") private User user; @Basic private String listOrder; ...Getters/Setters... } public class QueueItemPK implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name="movieID") private Integer movie; @Id @Column(name="userID") private Integer user; ...Getters/Setter... public int hashCode() { return (movie.getMovieID() + "|" + user.getUserID()).hashCode(); } public boolean equals(Object obj) { if (obj == this) return true; if (obj == null) return false; if (!(obj instanceof QueueItemPK)) return false; QueueItemPK pk = (QueueItemPK) obj; return pk.movie == movie && pk.user == user; } } 

正如你所看到的,他们必须拥有他们要匹配的id的类型。 不是很漂亮,但工作。 我建议在你的套装中使用generics; 使得更容易阅读和更安全的代码。