Как настроить отношение «многие ко многим» с помощью Junction Table с использованием JPA / EclipseLink - PullRequest
3 голосов
/ 18 мая 2009

У меня есть 2 таблицы:

Фильмы: movieID

Пользователи: * идентификатор пользователя 1005 *

Эти таблицы имеют отношение многие ко многим через таблицу очередей, с дополнительный атрибут listOrder:

Очередь: movieID, Идентификатор пользователя, 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. Я не совсем уверен, что это правильный путь сделать это.

Это ошибка: Описание исключения: несовместимое сопоставление [класс Movie] и [класс QueueItem]. Это обычно происходит, когда мощность отображения не соответствует мощности его backpointer. У меня такая же ошибка с классом User (ошибки чередуются).

Когда я снимаю аннотации @Id фильма и переменные пользователя в QueueItem и сделать некоторый другой ключ первичным ключом, однако он компилируется с без ошибок.

Будем благодарны за любые предложения.

Спасибо, B.J.

1 Ответ

2 голосов
/ 23 мая 2009

Прежде всего, как предположил Майк Корнелл, 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;
       }
}

Как вы видите, необходимо, чтобы у них был тип идентификатора, которому они должны соответствовать. не очень красиво, но работает. И я предлагаю использовать дженерики для ваших наборов; облегчает чтение и делает код более безопасным.

...