我有以下带注释的Hibernate实体类:
@Entity public class Cat { @Column(name = "ID") @GeneratedValue(strategy = GenerationType.AUTO) @Id private Long id; @OneToMany(mappedBy = "cat", cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Set<Kitten> kittens = new HashSet<Kitten>(); public void setId(Long id) { this.id = id; } public Long getId() { return id; } public void setKittens(Set<Kitten> kittens) { this.kittens = kittens; } public Set<Kitten> getKittens() { return kittens; } } @Entity public class Kitten { @Column(name = "ID") @GeneratedValue(strategy = GenerationType.AUTO) @Id private Long id; @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Cat cat; public void setId(Long id) { this.id = id; } public Long getId() { return id; } public void setCat(Cat cat) { this.cat = cat; } public Cat getCat() { return cat; } }
我的意图是在Cat和Kitten之间建立双向的一对多/多对一关系,Kitten是“拥有方”。
我想发生的是,当我创建一个新的Cat,然后是一个引用该Cat的新 小猫时,我Cat上的这组小猫应该包含新的Kitten 。但是,在以下测试 中不会发生这种情况 :
@Test public void testAssociations() { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); Transaction tx = session.beginTransaction(); Cat cat = new Cat(); session.save(cat); Kitten kitten = new Kitten(); kitten.setCat(cat); session.save(kitten); tx.commit(); assertNotNull(kitten.getCat()); assertEquals(cat.getId(), kitten.getCat().getId()); assertTrue(cat.getKittens().size() == 1); // <-- ASSERTION FAILS assertEquals(kitten, new ArrayList<Kitten>(cat.getKittens()).get(0)); }
即使在重新查询Cat之后,集合仍然为空:
// added before tx.commit() and assertions cat = (Cat)session.get(Cat.class, cat.getId());
我在这里对Hibernate期望过高吗?还是我自己来管理Collection的负担?在(注释)文档不作任何迹象表明我需要创造便利addTo*/ removeFrom*我的父对象的方法。
addTo*
removeFrom*
有人可以通过这种关系启发我对Hibernate的期望吗?或者,如果没有其他要求,请指向正确的Hibernate文档,该文档告诉我在这里应该发生的情况。
我该怎么做才能使父集合自动包含子实体?
它不会自动添加。您必须自己添加。
我也不会直接打电话Kitten.setCat()。典型的模式是将方法放入Cat:
Kitten.setCat()
Cat
public void addKitten(Kitten kitten) { if (kittens == null) { kittens = new HashSet<Kitten>(); } kittens.add(kitten); kitten.setCat(this); }
然后只需调用:
cat.addKitten(kitten);