在某些情况下,Hibernate会忽略属性

时间:2010-11-01 19:54:14

标签: hibernate jpa

我有一个包含另一个域对象的域对象;称它们为A和B. B包含一个可能很大的blob(图像文件)。只要我在A上只处理A一个A就不是一个问题。但是,有时我会处理成千上万的A,其中携带B上的blob会导致堆耗尽。当我处理这么多A时,我真的不需要B。

有没有办法告诉Hibernate忽略特定调用的这个属性?在这种情况下,我应该只做B瞬态并手动处理更新/删除吗?

现在要解决这个问题,我使用SQL查询来提取我想要的所有ID,然后遍历该列表,将每个域对象取出,执行我需要的操作,然后逐出它。

另外,我不能延迟加载B,因为我在servlet环境中所以在大多数情况下访问属性之前我的Hibernate会话已关闭。

@Entity
@Table(name="A")
public class A {

  private Long id

  @OneToOne(fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, orphanRemoval = true)
  @JoinColumn(name = "a_id", referencedColumnName = "b_id", nullable = true)
  @NotFound(action = NotFoundAction.IGNORE)
  private B b

  ...getters and setters
}

@Entity
@Table(name="B")
public class B {
  private Long id;
  private byte[] blob;

  ...getters and setters
}

由于

2 个答案:

答案 0 :(得分:7)

  

有没有办法告诉Hibernate忽略特定调用的这个属性?在这种情况下,我应该只做B瞬态并手动处理更新/删除吗?

一种选择是使用延迟属性获取(这需要字节码检测,请参阅文档)。所以你可以像这样映射B:

@Entity
@Table(name="B")
public class B {
  @Id
  private Long id;

  @Basic(fetch = FetchType.LAZY)
  @Lob
  private byte[] blob;

  // getters and setters
}

并且,如记录所示:

  

您可以在HQL中使用fetch all properties强制执行通常的热切提取属性。

对于这个特殊用例,另一种选择是使用不带B的替代版本的A(A')。

参考

答案 1 :(得分:1)

HQL的select clause会有帮助吗?通过将适当的构造函数添加到A,您可以让HQL返回A的集合,其中所有属性都加载b。如果我没记错的话,Hibernate Session不会跟踪这些部分对象,因此对该对象的更新不会刷新到DB。但在你的情况下,既然你接近Session,那可能无关紧要。