Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA CascadeType.REFRESH不工作?_Java_Jpa - Fatal编程技术网

Java JPA CascadeType.REFRESH不工作?

Java JPA CascadeType.REFRESH不工作?,java,jpa,Java,Jpa,我在JPA CascadeType.REFRESH属性方面遇到了一个奇怪的问题。 我有一个简单的父子关系,其中在父域对象(LineEquipmentFormat)中添加了如下级联属性 OneToMany(cascade = { CascadeType.REFRESH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy = "lineEquipmentFormat") public List<L

我在JPA CascadeType.REFRESH属性方面遇到了一个奇怪的问题。 我有一个简单的父子关系,其中在父域对象(LineEquipmentFormat)中添加了如下级联属性

OneToMany(cascade = { CascadeType.REFRESH, CascadeType.MERGE, CascadeType.PERSIST,
   CascadeType.REMOVE}, mappedBy = "lineEquipmentFormat")
 public List<LineEquipmentFormatDivision> getLineEquipmentFormatDivisions() {
  return lineEquipmentFormatDivisions;
 }
我正在使用JBoos5.1和Oracle10g

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


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

我添加了如下所示的级联属性(…),但当我从DB获取父LineEquipmentFormat对象时,我没有得到LineEquipmentFormatDivisions的列表

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

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

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

    SELECT f
    FROM LineEquipmentFormat f LEFT JOIN FETCH f.lineEquipmentFormatDivisions
    WHERE f.id = 1
    
  • 使用openentitymanager-In-View模式(在MVC上下文中)在请求传入时打开实体管理器,并将其保持打开状态,直到请求得到处理(Spring有一个或一个实现此模式的接口)


    • 谢谢您的评论

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

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

      LineEquipmentFormat lef=entityManager.find(LineEquipmentFormat.class,sysId); if(lef!=null&&lef.getLineEquipmentFormatDivisions()!=null){ lef.getLineEquipmentFormatDivisions().size(); }
      返回lef

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


    • 但我没听明白你的话。如果我在一个事务中提取LineEquipmentFormat,并立即在下一行获取分区列表,那么会话肯定没有关闭吗?我们也不鼓励使用fetchType属性,这样就排除了该选项!如果每次初始化父对象时都需要子成员,那么将fetchType设置为eager就没有问题。如果不是这样的话,那么只有在需要它们时,才需要急切地获取它们,您可以使用fetchjoin对它们进行查询。如果您在查询LineEquipmentFormat和尝试访问LineEquipmentFormatDivisions的位置发布代码,我们可能会更有帮助。例如,如果您说的是entityManager.find(LineEquipmentFormat.class,id),则会话将在此方法中打开和关闭。您应该使用FETCH JOIN
      SELECT f
      FROM LineEquipmentFormat f LEFT JOIN FETCH f.lineEquipmentFormatDivisions
      WHERE f.id = 1