Hibernate访问类属性不会加载真正的Hibernate对象

时间:2014-10-23 19:28:57

标签: java hibernate jpa entitymanager

在处理/不继承时,我在hibernate中有延迟加载的问题。我使用hibernate作为持久层。我的实体是使用JPA注释定义的。我正在使用Jboss。我正在使用数据源注入获取实体管理器。我正在使用容器管理的事务。 渴望不是正确的解决方案。

1)我有一个实体A引用第二个实体B.B实体有一些属性。我知道当我访问B的属性时,它应该被Hibernate加载。但它不会。我得到b_javaassist对象。但是我注意到当A对象被发送到客户端时,B对象被成功转换为真实对象。这是我的第一个案例。我不知道我的第二个案子和这个案子是一样的。所以我会告诉另一个项目。

A aInstance = em.find(A.class, 1);
aInstance.getB().getName();

@Entity @Table(name="a")
public class A {
    private B b;

}

@Entity @Table(name="b")
public class B {
    private String name;

 }

1)我有一个实体A引用第二个实体B.B实体引用了第三个子类实体。当访问B类的元素时,其中一些是BaseClass_javaasist代理,其中一些是SuperBaseClass_javaassist代理,其中一些是真正的SuperBaseClass对象。我不知道为什么会这样。你能告诉我我的情况有所不同吗?有什么解决方案?

A aInstance = em.find(A.class, 1);
aInstance.getB().getElements();

@Entity @Table(name="a")
public class A {
    private B b;

}

@Entity @Table(name="b")
public class B {
    private String name;
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name="elements",
      joinColumns={@JoinColumn(name="id", referencedColumnName="id")},
      inverseJoinColumns={@JoinColumn(name="element_id", referencedColumnName="element_id")})
    /** list of elements */
    private List<BaseClass> elements = new ArrayList<BaseClass>();

 }

@Entity @Table(name="superBaseClass")
public class SuperBaseClass extends BaseClass {

}

1 个答案:

答案 0 :(得分:3)

Hibernate使用代理来实现延迟加载。这意味着当你加载A时,这个A引用一个类的实例,它是B的子类,也是B的代理。所以它 IS 一个B,由继承规则和多态性。

首次在此代理上调用方法时,它通过从数据库获取B数据来初始化自身,执行代理B的方法,并返回与没有代理时相同的结果。因此没有问题。

您的BaseClass实例也会发生同样的情况。当您访问集合的元素时,其中一些已被引用为代理,因此Hibernate将代理放入集合中,以确保在同一会话中使用单个实例来引用同一实体。其他一些还没有,然后Hibernate将实际的类实例放入集合中。但这并不重要,因为它们都是BaseClass的实例。

所以基本上,它和做

一样
List<Number> list = new ArrayList<>();
list.add(new Integer(1));
list.add(new Long(2));

该列表包含Integer和Long实例,但它仍然是Number的列表,因为您将所有列表都列为List,所以您关心的一切都是正常的。