Как я могу получить информацию из соединительной таблицы, используя JPA / EclipseLink? - PullRequest
0 голосов
/ 18 мая 2009

У меня есть следующее отображение «многие ко многим»:

<pre> public class Student implements { @Id @GeneratedValue private Integer xID;</p> <pre><code>@ManyToMany @JoinTable(name = "x_y", joinColumns = { @JoinColumn(name = "xID")}, inverseJoinColumns={@JoinColumn(name="yID")}) private Set<Cat> cats;

}

открытый класс Cat реализует { @Я бы @GeneratedValue частное целое число yID;

@ManyToMany
@JoinTable(name = "x_y", 
           joinColumns = { @JoinColumn(name = "yID")},
           inverseJoinColumns={@JoinColumn(name="xID")})
private Set<Student> students;

}

Пожалуйста, игнорируйте имена объектов и свойств, они вымышленные и неактуальные. Это компилируется и работает нормально. Я также могу сделать это:

Entitymanager em = emf.createEntityManager();</p> <p>em.getTransaction().begin(); Student s = new Student(); Student s2 = new Student(); Cat c = new Cat(); em.persist(s); em.persist(s2); em.persist(c); s.getCats().add(c); c.getStudents().add(s2); em.getTransaction().commit();

Моя проблема возникает, когда я возвращаю объекты из базы данных.

em.getTransaction().begin(); Student s = em.find(Student.class, 2); Cat c = em.find(Cat.class, 3);</p> <p>if( c != null ) System.out.println(c.getYID() + ": " + c.getStudents()); if( s != null ) System.out.println(s.getXID() + ": " + s.getCats()); em.getTransaction().commit();

Распечатка:

3: {IndirectSet: не создан}

2: {IndirectSet: не создан}

Это вполне может быть нормальным поведением. Мне просто кажется, что когда я возвращаю объекты из таблицы, их наборы, относящиеся к другим объектам, должны быть заполнены. Что я хочу сказать, так это то, что соединительная таблица выглядит так:

X | Y

2 | 3

1 | 3

em.find (Cat.class, 3) должен возвращать объект Cat с набором {1,2} для getStudents (), а em.find (Student.class, 2) должен возвращать объект Student с набором из {3} для getCats ().

Есть ли способ сделать это возможным?

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

Ответы [ 2 ]

0 голосов
/ 19 мая 2009

Возможно, лучшим примером был бы:

em.getTransaction().begin(); Student s = new Student(); Student s2 = new Student(); Cat c = new Cat(); em.persist(s); em.persist(s2); em.persist(c); c.getStudents().add(s); c.getStudents().add(s2); em.getTransaction().commit();

и затем пытается сказать

Cat c2 = em.find(Cat.class,c.getYID()); Student s3 = em.find(Student.class,s.getXID()); System.out.println(c2.getYID() + ": " + c2.getStudents()); System.out.println(s3.getXID() + ": " + s3.getCats());

Указанные выше отпечатки:

1: {[[Movie: movieID = 2], [Movie: movieID = 3]]}

2: {[]}

Это не имеет смысла для меня, так как у кошки с id = 1 в своем наборе есть фильм с id = 2, но у фильма с id = 2 нет набора кошек с id = 1. (Изменение типа каскада, похоже, не повлияло на результаты.)

Большое спасибо за ответ.

B.J.

0 голосов
/ 18 мая 2009

Попробуйте добавить @ManyToMany (cascade = CascadeType.ALL) к вашему объекту Cat для каскадирования ваших операций чтения.

При правильной настройке каскадирования вы можете изменить код сохранения на;

Entitymanager em = emf.createEntityManager();

em.getTransaction().begin(); 
Student s = new Student(); 
Student s2 = new Student();
Cat c = new Cat();
// this should be c.setStudents(s2)
c.getStudents().add(s2); 
em.persist(c); 
em.getTransaction().commit(); 

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

Вам также может понадобиться явно указать тип извлечения: @ManyToMany (fetch = FetchType.LAZY) или FetchType.EAGER.

...