有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

请提供有关此错误可能根本原因的更多信息

谢谢


共 (3) 个答案

  1. # 1 楼答案

    谢谢你的评论

    以下是我们最终实现它的方式

    1. 在获取“LineEquipmentFormat”父对象时,我们添加了以下附加代码。

      LineEquipmentFormat lef=entityManager。查找(LineEquipmentFormat.class,sysId); if(lef!=null&;lef.getLineEquipmentFormatDivisions()!=空){ 莱夫。getLineEquipmentFormatDivisions()。大小(); }
      返回lef

    2. 现在,如果我们可以从这个父对象获取子列表

  2. # 2 楼答案

    I have added the cascade attributes like below (...) But when I fetch the parent LineEquipmentFormat object from DB, I do not get the list of LineEquipmentFormatDivisions.

    级联操作与急加载或延迟加载几乎没有关系,在您的情况下,您得到的错误(臭名昭著的LazyInitializationException)意味着您正试图访问一个延迟关联,但会话已经关闭(因此Hibernate无法加载它)

    要避免此“问题”,请执行以下操作之一:

    • 急切地使用fetchType属性加载关联(如果在大多数情况下不需要关联,我会把“口红涂在猪身上”)
    • 对于这个特定的用例,在执行查询时使用FETCH JOIN获取关联,例如:

      SELECT f
      FROM LineEquipmentFormat f LEFT JOIN FETCH f.lineEquipmentFormatDivisions
      WHERE f.id = 1
      
    • 在视图中使用打开EntityManager模式(在MVC上下文中)在请求进入时打开实体管理器,并将其保持打开状态,直到请求得到处理(Spring有一个Serlvet filter或一个Interceptor实现此模式)

  3. # 3 楼答案

    当您将级联类型定义为refresh时,这意味着entityManager。refresh()在父LineEquipmentFormat上调用,在子LineEquipmentFormatDivisions上也将调用。但是,您收到的错误表明您试图在会话关闭时延迟初始化集合。如果在会话关闭后需要此集合,则需要通过设置fetchType急切地获取它们