我有一个Hibernate对象如下:
@Entity
@Table(name="SOME_TABLE")
public class SomeEntity {
private Long id;
private String someInfo;
@Id
@Column(name = "ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "SOME_INFO")
public String getSomeInfo() {
return someInfo;
}
public void setSomeInfo(String someInfo) {
this.someInfo = someInfo;
}
}
使用以下代码加载对象时:
sessionFactory.getCurrentSession().load(getEntityClass(), id);
未加载对象的字段,而是返回代理对象,并且仅当我通过其getter方法显式调用它们时才加载实际字段。
据我所知,应该急切地加载普通字段(基元,字符串)。为什么不是关系或集合的字段是懒惰加载的?有没有办法让Hibernate急切地加载它们?
这对我来说是有问题的,因为我使用此对象作为Spring REST应用程序的返回值,然后我得到could not initialize proxy - no Session
异常。
答案 0 :(得分:2)
获取代理的原因是,允许Session#load
合同将代理作为占位符返回,而不必查询指定对象的数据库。这也是为什么您希望加载的标识符存在至关重要的原因,因为如果您将在以后遇到意外的ObjectNotFoundException
错误。
您想要使用的是Session#get
,它可以保证查询数据库并且不会返回代理,因此您提到的那些基本属性将按照您的预期急切加载。
例如:
final Comment comment = new Comment( "This is a comment" );
comment.setOwner( session.load( Product.class, productId ) );
session.save( comment );
这里的好处是Product
没有完全初始化。我们使用指定的productId
值创建持久代理,并将其关联为注释的所有者。当我们持久保存新的Comment
以使外键关系发生而不必实际加载Product
状态时,这就足够了,从而避免了不必要的开销。