【发布时间】:2017-04-13 08:29:31
【问题描述】:
我最近将一个使用本机 Hibernate 实体和会话管理的项目转移到 Spring,并带有注释驱动的依赖注入和事务管理。
我有一个这样的实体结构:
@Entity
@Table(name = "PARENT",uniqueConstraints=@UniqueConstraint(columnNames={"parentName"}))
public class Parent implements Serializable, {
static final long serialVersionUID = 1L;
@Id
private int id;
@OneToMany(mappedBy = "parent", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Set<Child> child = new HashSet<Child>();
}
@Entity
@Table(name = "CHILD", uniqueConstraints = @UniqueConstraint(columnNames = {
"childName", "parent_id" }))
@SequenceGenerator(name = "CHILD_SEQ", allocationSize = 1, sequenceName = "CHILD_SEQ")
public class Child implements Serializable {
static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CHILD_SEQ")
private int id;
private String childName = ""; //$NON-NLS-1$
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
}
这就是发生的事情。
-
我得到了所有包含子对象单独列表的父对象。这工作很快,我在调试器的内存中有完整的对象树,我可以看到每个子对象都正确加载。
public List<Parent> getParents() { return em.createQuery("from Parent",Parent.class).getResultList(); } -
然后我尝试获取每个 Child 对象,应用程序冻结我的电脑变慢,几个小时后我得到 Out on memory 异常。
public List<Child> getChildren() { return em.createQuery("from Child",Child.class).getResultList(); }
我查看了生成的 SQL,对于第一种方法,它似乎在逻辑上将调用分解为单独的对象集,而在几秒钟内,它似乎构建了一个我无法真正遵循的怪物大小的查询,并且查询似乎没有返回,虽然我不能确定。
我无法理解的是为什么对父项的查询工作得如此之快,并且给了我每个对象,但子查询却中断了。
【问题讨论】:
-
能分享一下持久化逻辑吗
-
格式有问题。
-
尝试使用 em.persist 而不是合并,因为持久化对象不会被管理,如果这不起作用,请共享调用 saveChild() 的代码
-
FetchType.EAGER有什么具体原因吗?除非有很好的理由,否则应该是FetchType.LAZY,因为EAGER有加载非常大的对象图的风险,这可能导致OutOfMemory异常。 -
那么您在数据库中真正有多少孩子?
标签: java spring hibernate jpa persistence