从hibernate会话中删除对象

从hibernate会话中删除对象,hibernate,exception,lazy-initialization,Hibernate,Exception,Lazy Initialization,对于类B,我有hibernate pojo类A{B;其他一些属性},lazy=true。 当我得到对象A时,B没有加载,hibernate返回它的代理。当我将这个对象传递给另一个模块时,该模块遍历A中的每个对象,当它遇到B.getXXX时,抛出LazyInitialization异常。在这种特殊情况下,我不想加载类B,因为它不是必需的。当我调用B上的方法时,有没有办法返回null或将B的代理转换为实际对象B,这样模块就不会抛出LazyInitialization错误。我无法更改类B getter

对于类B,我有hibernate pojo类A{B;其他一些属性},lazy=true。
当我得到对象A时,B没有加载,hibernate返回它的代理。当我将这个对象传递给另一个模块时,该模块遍历A中的每个对象,当它遇到B.getXXX时,抛出LazyInitialization异常。在这种特殊情况下,我不想加载类B,因为它不是必需的。当我调用B上的方法时,有没有办法返回null或将B的代理转换为实际对象B,这样模块就不会抛出LazyInitialization错误。我无法更改类B getter、setter,因为它是公共类,并被许多其他类使用。

如果我理解您的问题,您正在检索一个与B有惰性关联的对象A。但是,此关联未初始化,并且您发现其他模块正在抛出异常,因为B实际被使用。因此,它在某种程度上是必需的

你想不想

  • 从对
    B
    的调用返回
    null
    (据我所知,这是不可能的,除非那些模块上有一些只有您才能知道的特定于应用程序的行为)或

  • 发生此类调用时初始化
    B
    。我会尽力帮你实现这个

获取
LazyInitializationExceptions
的原因是获取
B
(并且没有初始化它)的会话已经关闭,因此此时,
B
的实例没有任何用处。您可以在这里应用的一种解决方法是使用,以便在所有请求范围中打开相同的Hibernate会话。此会话将使用lazy
B
获取
A
,并在需要时初始化
B

您可以应用的另一个选项是在另一个会话中初始化
B
(仅当这些异常发生在另一个事务的上下文中时有效,也就是说,在另一个Hibernate会话打开的情况下,与获取
A
的会话不同)。例如:

session.update(a.getB());
当然,您始终可以使用
fetchMode.EAGER
Hibernate.initialize(a.getB())
强制初始化
B
。但这将是无条件加载实例,即使它根本不会被使用


此外,您可能会发现这个问题的答案可能很有用:

如果我理解您的问题,您正在检索一个与B有惰性关联的对象A。但是,此关联未初始化,并且您发现其他模块正在抛出异常,因为实际使用了B。因此,它在某种程度上是必需的

你想不想

  • 从对
    B
    的调用返回
    null
    (据我所知,这是不可能的,除非那些模块上有一些只有您才能知道的特定于应用程序的行为)或

  • 发生此类调用时初始化
    B
    。我会尽力帮你实现这个

获取
LazyInitializationExceptions
的原因是获取
B
(并且没有初始化它)的会话已经关闭,因此此时,
B
的实例没有任何用处。您可以在这里应用的一种解决方法是使用,以便在所有请求范围中打开相同的Hibernate会话。此会话将使用lazy
B
获取
A
,并在需要时初始化
B

您可以应用的另一个选项是在另一个会话中初始化
B
(仅当这些异常发生在另一个事务的上下文中时有效,也就是说,在另一个Hibernate会话打开的情况下,与获取
A
的会话不同)。例如:

session.update(a.getB());
当然,您始终可以使用
fetchMode.EAGER
Hibernate.initialize(a.getB())
强制初始化
B
。但这将是无条件加载实例,即使它根本不会被使用


此外,您可能会发现这个问题的答案可能很有用:

实际上,您有一些选择

1) 使A->B关系更为密切

2) 当您在hibernate会话已关闭的情况下尝试启动代理时,会出现
LazyInitializationExceptions
。所以,可能的解决方案是保持会话打开,直到所有A、B、C…等对象操作都未完成

3) 若您正在记录有关WEB环境的信息,那个么视图中有一个名为OpenSession的模式。这将使您的Hibernate会话保持打开状态,直到您的HTTP请求处于活动状态


我想你可以多读一些。我认为你读它会很有用。

实际上,你有几个选择

1) 使A->B关系更为密切

2) 当您在hibernate会话已关闭的情况下尝试启动代理时,会出现
LazyInitializationExceptions
。所以,可能的解决方案是保持会话打开,直到所有A、B、C…等对象操作都未完成

3) 若您正在记录有关WEB环境的信息,那个么视图中有一个名为OpenSession的模式。这将使您的Hibernate会话保持打开状态,直到您的HTTP请求处于活动状态


我想你可以多读一些。我认为您阅读它会很有用。

会话关闭时,不要将实体发送到其他模块

如果这些其他模块与会话在同一应用程序域中执行,则在调用模块时保持会话打开,并在返回时关闭会话


如果这些模块不在同一AppDomain中,如果您需要某种序列化来发送对象,或者如果异步调用它,我将使用DTO。在服务器外部公开实体(我不知道这里是否是这种情况)是一种不好的做法,原因有几个。Ayende Rahien将其称为。

会话结束时,不要将实体发送到其他模块