@ManyToOne引用的getId()上的LazyInitializationException

时间:2016-01-26 12:16:20

标签: java hibernate lazy-loading many-to-one lazy-initialization

当我尝试访问分离实体的惰性@ManyToOne引用的ID时,我正面临<html:form enctype="multipart/form-data" action=<%="/saveInstr.do?org.apache.struts.taglib.html.TOKEN="+session.getAttribute(Globals.TRANSACTION_TOKEN_KEY)%> method="POST"> 。我不想完全获取引用,但只需要ID(它应该存在于原始对象中,以便以惰性/延迟方式获取引用)。

LazyInitializationException

要解释一下,如何在不实际获取整个LazyReference的情况下访问LazyReference的ID(实际存在于EntityA的初始选择中)?

3 个答案:

答案 0 :(得分:3)

当使用字段访问时,Hibernate将getId()方法视为与任何其他方法相同,这意味着调用它会触发代理初始化,因此如果在分离的实例上调用,则会导致LazyInitializationException

要仅对id属性使用属性访问(同时保留所有其他属性的字段访问权限),请为id字段指定AccessType.PROPERTY

@Entity
public class A {
  @Id
  @Access(AccessType.PROPERTY)
  private int id;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }
}

答案 1 :(得分:1)

这应该是可能的。我只能获得@ManyToOne LAZY实体的ID。

但是为此我已经在实体的getter上设置了注释,而不是直接在实例变量上设置它们,这导致了null值。

我相信你正在对实例变量使用注释。您可以尝试使用getter注释,看看它是否对您有所帮助。

答案 2 :(得分:0)

你得到一个LazyInitializationException异常,因为Hibernate用你的代理对象包装你的持久化。代理为惰性对象的任何getter生成异常,即使id当然已经拥有LazyReference

要获得id没有LazyInitializationException,您可以使用this method(您可以参考其他有趣的利用方法的链接)

@SuppressWarnings("unchecked")
public static <T> T getPid(Persistent<?> persistent) {
    if (persistent == null) {
        return null;
    }

    if (!(persistent instanceof HibernateProxy) || Hibernate.isInitialized(persistent)) {
        return (T) persistent.getPid();
    }

    LazyInitializer initializer = ((HibernateProxy) persistent).getHibernateLazyInitializer();
    return (T) initializer.getIdentifier();
}

Persistent是所有持久性的基类。对于LazyReference,您可以像这样重写代码

@SuppressWarnings("unchecked")
public static Long getId(LazyReference persistent) {
    if (persistent == null) {
        return null;
    }

    if (!(persistent instanceof HibernateProxy) || Hibernate.isInitialized(persistent)) {
        return persistent.getId();
    }

    LazyInitializer initializer = 
        ((HibernateProxy) persistent).getHibernateLazyInitializer();
    return initializer.getIdentifier();
}