Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate ignore property under some circumstances

Tags:

hibernate

jpa

I have a domain object that contains another domain object; call them A and B. B contains a blob (an image file) which can be large. As long as I am only dealing with one A at a time having B on A isn't a concern. However, sometimes I'll be dealing with thousands of A in which carrying around the blob on B causes heap to run out. When I am dealing with so many A I really don't need B anyway.

Is there some way of telling Hibernate to ignore this property for a particular call? Should I just make B transient and deal with updating/deleting manually in this case?

Right now to get around this problem I use a SQL query to pull all the ids I want then iterate over that list getting each domain object out, doing what I need, then evicting it.

Also, I can't lazy load B because I'm in a servlet environment so my Hibernate session is closed before I access the properties in most cases.

@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
}

Thanks

like image 931
Josh Avatar asked Feb 25 '23 22:02

Josh


2 Answers

Is there some way of telling Hibernate to ignore this property for a particular call? Should I just make B transient and deal with updating/deleting manually in this case?

One option would be to use lazy property fetching (this requires bytecode instrumentation, refer to the documentation). So you could map B like this:

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

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

  // getters and setters
}

And, as documented:

You can force the usual eager fetching of properties using fetch all properties in HQL.

Another option would be to use an alternative version of A (A') without the B, for this special use case.

References

  • Hibernate Annotations Reference Guide
    • 2.2.2. Mapping simple properties
  • Hibernate Core Reference Guide
    • 20.1.8. Using lazy property fetching
like image 183
Pascal Thivent Avatar answered Mar 04 '23 04:03

Pascal Thivent


Will the select clause of HQL help? With the appropriate constructor added to A, you can have the HQL return a collection of As with all properties expect b loaded. If I remember correctly, the Hibernate Session does not track such partial objects, so updates made to the object wont be flushed to the DB. But in your case, since you close to Session anyway, it might not matter.

like image 33
Binil Thomas Avatar answered Mar 04 '23 03:03

Binil Thomas