javajpa级联类型。刷新不工作?
我面临着一个关于JPA的奇怪问题。刷新属性。 我有一个简单的父子关系,在父域对象(LineEquipmentFormat)中,我添加了如下级联属性
OneToMany(cascade = { CascadeType.REFRESH, CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REMOVE}, mappedBy = "lineEquipmentFormat")
public List<LineEquipmentFormatDivision> getLineEquipmentFormatDivisions() {
return lineEquipmentFormatDivisions;
}
但是,当我从DB中获取父LineEquipmentFormat对象时,我没有得到LineEquipmentFormatDivisions的列表
我犯的错误是
17:46:34,251 ERROR [LazyInitializationException] failed to lazily initialize a collection of role: LineEquipmentFormat.lineEquipmentFormatDivisions, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: LineEquipmentFormat.lineEquipmentFormatDivisions, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
at org.hibernate.collection.PersistentBag.toString(PersistentBag.java:506)
我正在使用Jboos 5.1和Oracle 10G
请提供有关此错误可能根本原因的更多信息
谢谢
# 1 楼答案
谢谢你的评论
以下是我们最终实现它的方式
在获取“LineEquipmentFormat”父对象时,我们添加了以下附加代码。
LineEquipmentFormat lef=entityManager。查找(LineEquipmentFormat.class,sysId); if(lef!=null&;lef.getLineEquipmentFormatDivisions()!=空){ 莱夫。getLineEquipmentFormatDivisions()。大小(); }
返回lef
现在,如果我们可以从这个父对象获取子列表
# 2 楼答案
级联操作与急加载或延迟加载几乎没有关系,在您的情况下,您得到的错误(臭名昭著的
LazyInitializationException
)意味着您正试图访问一个延迟关联,但会话已经关闭(因此Hibernate无法加载它)要避免此“问题”,请执行以下操作之一:
fetchType
属性加载关联(如果在大多数情况下不需要关联,我会把“口红涂在猪身上”)对于这个特定的用例,在执行查询时使用
FETCH JOIN
获取关联,例如:在视图中使用打开EntityManager模式(在MVC上下文中)在请求进入时打开实体管理器,并将其保持打开状态,直到请求得到处理(Spring有一个Serlvet filter或一个Interceptor实现此模式)
# 3 楼答案
当您将级联类型定义为refresh时,这意味着entityManager。refresh()在父LineEquipmentFormat上调用,在子LineEquipmentFormatDivisions上也将调用。但是,您收到的错误表明您试图在会话关闭时延迟初始化集合。如果在会话关闭后需要此集合,则需要通过设置fetchType急切地获取它们