没有关系的Hibernate懒惰对象

时间:2017-01-31 17:49:11

标签: java hibernate rest spring-rest

我有一个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异常。

1 个答案:

答案 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状态时,这就足够了,从而避免了不必要的开销。