JPA和Hibernate代理行为 [英] JPA and Hibernate proxy behavior
问题描述
我试图观察下面的JPA2/Hibernate4代理行为,
i tried to observe JPA2 / Hibernate4 proxy behavior below,
//具有延迟加载的循环实体:
// Circular entity with lazy loading:
@Entity
public class Employee {
@Id@Generated
int id;
String name;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
Employee boss;
public String toString() {
return id + "|" + name + "|" + boss;
}
//getters and setters ...
}
//坚持存在的实体
// Outer entity:
Employee employee = new Employee();
employee.setName("engineer");
// Inner entity:
Employee boss = new Employee();
boss.setName("manager");
employee.setBoss(boss);
entityTransaction.begin();
entityManager.persist(employee);
entityTransaction.commit();
System.out.println(employee);
//输出:
Hibernate: insert into Employee (id, boss_id, name) values (default, ?, ?)
Hibernate: insert into Employee (id, boss_id, name) values (default, ?, ?)
2|engineer|1|manager|null
//加载外部实体:
String queryString = "select e from Employee e where e.id=" + employee.getId();
Query query = entityManager.createQuery(queryString);
Object loadedEmployee = query.getSingleResult();
System.out.println(loadedEmployee.getClass().getSimpleName());
//输出:
Hibernate: select employee0_.id as id2_, employee0_.boss_id as boss3_2_, employee0_.name as name2_ from Employee employee0_ where employee0_.id=2 limit ?
Employee
令我惊讶的是,上面加载的外部实体仍然是普通实体,但是我希望它是Hibernate proxy
由lazy loading
产生的结果.我可能在这里错过了一些东西,那么如何正确处理呢?一个简单而具体的示例将不胜感激!
To my surprise the loaded outer entity above is still the plain one, but i'd expected it to be Hibernate proxy
resulting from lazy loading
. I could have missed something here, so how to get it right? A simple yet concrete example is much appreciated!
@EDIT
根据来自@kostja
的回答,我修改了代码并在下面的SE模式下对其进行了调试,因此既无法生成LazyInitializationException
,也无法对其进行代理.还有其他提示吗?
According to the answer from @kostja
i adapted the code and debugged it in SE mode below, neither could LazyInitializationException
be produced, nor was boss property
proxied. Any further hints?
@EDIT 2
最后,我将确认@kostja
的答案无疑是很棒的.
Finally, i'd confirm that the answer from @kostja
is undoubtly great.
我在EE模式下进行了测试,因此在下面观察到了proxied boss property
,
I tested in EE mode, so the proxied boss property
was observed below,
//LazyInitializationException
抛出:
public Employee retrieve(int id) {
Employee employee = entityManager.find(Employee.class, id);
// access to the proxied boss property outside of persistence/transaction ctx
Employee boss = employee.getBoss();
System.out.println(boss instanceof HibernateProxy);
System.out.println(boss.getClass().getSimpleName());
return boss;
}
//放置Spring Tx
后绿灯:
@Transactional
public Employee retrieve(int id) ...
//输出:
true
Employee_$$_javassist_0