0

我有以下多对多映射:

public class Student implements
{
    @Id
    @GeneratedValue
    private Integer xID;

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

}

public class Cat implements { @Id @GeneratedValue private Integer yID;

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

}

请忽略对象和属性名称,它们是虚构的和不相关的。这可以编译并正常工作。我也可以这样做:

Entitymanager em = emf.createEntityManager();

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

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 | 是

2 | 3

1 | 3

em.find(Cat.class,3) 应该为 getStudents() 返回一个带有一组 {1,2} 的 Cat 对象,而 em.find(Student.class,2) 应该返回一个带有一组 {3 的 Student 对象} 对于 getCats()。

有没有办法让这成为可能?

谢谢, BJ

4

2 回答 2

0

尝试将 @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。

于 2009-05-18T19:52:23.147 回答
0

也许一个更好的例子是:

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:{[[电影:movieID=2],[电影:movieID=3]]}

2:{[]}

这对我来说毫无意义,因为 id=1 的猫在其集合中具有 id=2 的电影,但 id=2 的电影在其集合中没有 id=1 的猫。(更改级联类型似乎不会影响结果。)

非常感谢您的回复。

北京

于 2009-05-18T21:20:42.657 回答