我尝试使用Hibernate和JPA调试预先存在的代码。错误信息是有道理的,甚至还有其他几个问题在讨论它。但当我寻找一个开放的会议时,我发现"会话"在整个代码体中都没有提到(除了HTTP会话 - 一个完全不同的东西)。此外,代码看起来应该工作,这让我相信有一些我无法看到的状态信息,但我无法弄清楚我应该尝试寻找什么类型的状态。
我尝试发布一个简单的例子,虽然由于所涉及的所有依赖关系,我无法验证以下内容会做同样的事情。希望只要说这个例外100%可靠地被抛出就足以让我相信我只是忽视了一些相当微不足道的事情。
代码获取如下定义的类的实例:
@Entity
@Table(name = "some_object")
public class SomeObject {
@Valid
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "other_object_id")
private OtherObject otherObject;
// ...lots of other declarations
public OtherObject getOtherObject() {return this.otherObject;}
// ...lots of other accessors
}
从这个实例中,获取另一个对象,依次在其上调用一个属性:
OtherObject other = someObject.getOtherObject();
String strVal = otherObject.getOtherString();
其中OtherObject声明为(部分)如下:
@Entity
@Table(name = "other_object")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class OtherObject {
@NotEmpty
@Column(name = "other_string")
private String otherString;
// ...
public String getOtherString() { return this.otherString; }
// ...
}
从LazyInitializationException
检索字符串时发生otherObject
。
为什么我没有获得LIE
获取someObject
(通过某些我认为的JPA代码获取的内容与此无关)?
我认为我可以假设,因为第一个访问器可能导致数据库查询成功返回,第二个访问器也应该如此。这是不正确的吗?
或许otherObject
已经#34;已经在这里",并且不会导致查询,而检索otherString
则不会。我该怎么测试呢?在任何地方都没有代码处理Session
个实例,并且对detach
个对象的任何调用似乎都发生在完全不适用的位置。我应该更加努力吗?我是否应该追求兔子洞,让Hibernate SQL日志在Tomcat中工作似乎是?
或者没有办法说出我在这里给出了什么?我应该添加更多细节吗?
答案 0 :(得分:2)
由于otherObject
是懒惰地获取的,因此当您执行getOtherObject()
时,没有数据库查询。返回惰性代理对象。如果要检查其内容,即发生otherObject.otherString
数据库访问。
如果您没有在事务上下文中工作(即会话未打开),则会获得LazyInitializationException
。您可以通过急切地获取otherObject
(如何完成取决于您如何加载初始SomeObject
)或通过打开事务/会话以便可以懒惰地执行查询来解决此问题。
记录Hibernate完成的SQL查询也不是很难。