Hibernate注释多对一不将子集合添加到父集合
我有以下带注释的 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 是“拥有方”。
我想要发生的是,当我创建一只新猫,然后是引用该猫的新小猫时,我的猫上的小猫集应该包含新小猫。然而,在下面的测试中,这种情况不会发生:
@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 后,Set 仍然是空的:
// added before tx.commit() and assertions
cat = (Cat)session.get(Cat.class, cat.getId());
我对 Hibernate 的期望是否过高?或者我有责任自己管理馆藏? (注释)文档不会做任何指示我需要在父对象上创建便捷的 addTo*
/removeFrom*
方法。
有人可以告诉我在这种关系下我对 Hibernate 的期望是什么吗?或者,如果没有别的事,请向我指出正确的 Hibernate 文档,它告诉我在这里应该发生什么。
我需要做什么才能使父集合自动包含子实体?
I have the following annotated Hibernate entity classes:
@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; }
}
My intention here is a bidirectional one-to-many/many-to-one relationship between Cat and Kitten, with Kitten being the "owning side".
What I want to happen is when I create a new Cat, followed by a new Kitten referencing the Cat, the Set of kittens on my Cat should contain the new Kitten. However, this does not happen in the following test:
@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));
}
Even after re-querying the Cat, the Set is still empty:
// added before tx.commit() and assertions
cat = (Cat)session.get(Cat.class, cat.getId());
Am I expecting too much from Hibernate here? Or is the burden on me to manage the Collection myself? The (Annotations) documentation doesn't make any indication that I need to create convenience addTo*
/removeFrom*
methods on my parent object.
Can someone please enlighten me on what my expectations should be from Hibernate with this relationship? Or if nothing else, point me to the correct Hibernate documentation that tells me what I should be expecting to happen here.
What do I need to do to make the parent Collection automatically contain the child Entity?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它不会自动添加它。你必须自己添加它。
我也不会直接调用
Kitten.setCat()
。典型的模式是将一个方法放入Cat
中,例如:然后简单地调用:
It won't automatically add it. You have to add it yourself.
I wouldn't directly call
Kitten.setCat()
either. The typical pattern for this is to put a method inCat
like:and then simply call:
当使用双向关联时,您必须处理“链接”的两侧,并且为此使用防御性链接管理方法是很常见的,正如 @cletus 所建议的。来自 Hibernate 核心文档:
更多参考
When working with bi-directional associations, you have to handle both sides of the "link" and it is very common to use defensive link management methods for that, as suggested by @cletus. From Hibernate Core documentation:
More References