以下の JPA2/Hibernate4 プロキシの動作を観察しようとしましたが、
// 遅延読み込みによる循環エンティティ:
@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
. ここで何かを見逃した可能性があるので、どうすれば正しくなりますか?シンプルで具体的な例は大歓迎です!
@編集
私からの回答によると、@kostja
以下のコードを適応させてSEモードでデバッグしたところ、LazyInitializationException
生成もboss property
プロキシもされませんでした。さらにヒントはありますか?
@EDIT 2
最後に、からの答え@kostja
が間違いなく素晴らしいことを確認します。
私はEEモードでテストしたので、proxied boss property
以下が観察されました。
//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
また、20.1.4 を参照できます。Hibernate ドキュメントからのコレクションとプロキシの初期化。