Julian Kreuzer
Julian Kreuzer

Reputation: 356

Hibernate doesn't fetch eager

I have tow classes, the "Article" which contains a @ManyToOne reference to a "SurchargeGroup" which specifies the surcharge for that article.

@Entity
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(doNotUseGetters = true)
@Audited
public final class Article {

  @Id
  @GeneratedValue(generator = "increment")
  @GenericGenerator(name = "increment", strategy = "increment")
  @Getter(onMethod_ = {@Key(PermissionKey.ARTICLE_ID_READ)})
  @Setter(onMethod_ = {@Key(PermissionKey.ARTICLE_ID_WRITE)})
  private int id;


  @JoinColumn(nullable = false)
  @ManyToOne
  @Getter(onMethod_ = {@Key(PermissionKey.SURCHARGE_TABLE_SUPPLIER_READ)})
  @Setter(onMethod_ = {@Key(PermissionKey.SURCHARGE_TABLE_SUPPLIER_WRITE)})
  private SurchargeGroup surchargeGroup;

}

The other class "SurchargeGroup" contains a parent object reference which can inherit the surcharge to the "SurchargeGroup" if it isn't set the case that no surcharge is provided by any parent is not possible.


@Table
@Entity
@EqualsAndHashCode(doNotUseGetters = true)
@Audited
public class SurchargeGroup implements Serializable, Cloneable {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column
  @Getter(onMethod_ = {@Key(PermissionKey.SURCHARGE_TABLE_ID_READ)})
  @Setter(onMethod_ = {@Key(PermissionKey.SURCHARGE_TABLE_ID_WRITE)})
  private int id;

  @Column
  @Setter(onMethod_ = {@Key(PermissionKey.SURCHARGE_TABLE_SURCHARGE_WRITE)})
  private Double surcharge;

  @Column
  @Getter(onMethod_ = {@Key(PermissionKey.SURCHARGE_TABLE_NAME_READ)})
  @Setter(onMethod_ = {@Key(PermissionKey.SURCHARGE_TABLE_NAME_WRITE)})
  private String name;

  @JoinColumn
  @ManyToOne(fetch = FetchType.EAGER)
  @Getter(onMethod_ = {@Key(PermissionKey.SURCHARGE_TABLE_SUPPLIER_READ)})
  @Setter(onMethod_ = {@Key(PermissionKey.SURCHARGE_TABLE_SUPPLIER_WRITE)})
  private SurchargeGroup parent;

  public double getSurcharge() {
    if (surcharge == null) {
      return parent == null
          ? supplier == null
              ? Setting.SURCHARGE_DEFAULT.getDoubleValue()
              : supplier.getDefaultSurcharge()
          : parent.getSurcharge();
    } else return surcharge;
  }

 @JoinColumn
  @ManyToOne
  @Getter(onMethod_ = {@Key(PermissionKey.SURCHARGE_TABLE_SUPPLIER_READ)})
  @Setter(onMethod_ = {@Key(PermissionKey.SURCHARGE_TABLE_SUPPLIER_WRITE)})
  private Supplier supplier;
}

My problem is now that if I call the "getSurcharge()" method I get this exception which I cannot explain to myself because I marked the surcharge group to fetch eager

Exception in thread "AWT-EventQueue-0" org.hibernate.LazyInitializationException: could not initialize proxy [kernbeisser.DBEntities.SurchargeGroup#1046] - the owning Session was closed
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:172)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:309)
    at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:45)
    at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95)
    at kernbeisser.DBEntities.SurchargeGroup$HibernateProxy$cdTAuBkS.getSurcharge(Unknown Source)

I asked myself if this could get caused by the @Audited annotation? Any ideas? Thanks a lot!

Note: the @Key annotations have no effect to this scenario.

Here is what the debugger shows (Sorry for the German toString() functions): This is what the debugger shows

Upvotes: 2

Views: 207

Answers (2)

Guillaume
Guillaume

Reputation: 14656

Hibernate needs to stop eagerly fetching associations at some point, otherwise it would need to join an infinite number of times the SurchargeGroup entity (since it references itself).

The depth these fetches can be controlled application wide using the hibernate.max_fetch_depth property.

Upvotes: 1

Julian Kreuzer
Julian Kreuzer

Reputation: 356

The source of the error was the AuditReader it doesn't fetch all eager properties even if they are annotated as Fetch.EAGER It looks like the AuditReader only fetches one level of eager relations:

Article -> SurchargeGroup -> SurchargeGroup -> ... (fetched) (fetched) (not fetched)

Upvotes: 0

Related Questions