多数の外部キー関係を持つデータベースの ORM として Hibernate を使用しています。問題は、これらの関連するデータセットをフェッチしたい場合とそうでない場合があるため、これらのコレクションで「フェッチ」を「遅延」に設定したことです。残念ながら、セッションが閉じられているため、これらのオブジェクトをシリアライズしようとするたびに、Hibernate は LazyInitializationException をスローします。OpenSessionInView フィルターを使用すると、Hibernate がこれらのコレクションにデータを入力するだけになり、そもそも遅延コレクションを持つという目的全体が無効になります。
LIE をトリガーせずに、すべての遅延コレクションにデータを入力する必要なく、POJO に入力されたデータをシリアル化または抽出する簡単な方法はありますか?
編集:これは、Departments と 1 対多の関係にある子である "Departments" と "Employees" の 2 つのテーブルを処理して、作業しようとしているコードの例です。データベースにリストされている部門を表示できるようにしたいのですが、その部門に属するすべての従業員をロードする必要はありません。
部門:
package com.test.model;
// Generated Apr 7, 2012 7:10:28 PM by Hibernate Tools 3.4.0.CR1
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* Departments generated by hbm2java
*/
@Entity
@Table(name="Departments"
,catalog="test"
)
public class Departments implements java.io.Serializable {
private Integer id;
private String name;
private Set<Employees> employeeses = new HashSet(0);
public Departments() {
}
public Departments(String name) {
this.name = name;
}
public Departments(String name, Set employeeses) {
this.name = name;
this.employeeses = employeeses;
}
@Id @GeneratedValue(strategy=IDENTITY)
@Column(name="Id", unique=true, nullable=false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="Name", nullable=false)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(fetch=FetchType.LAZY, mappedBy="departments")
public Set<Employees> getEmployeeses() {
return this.employeeses;
}
public void setEmployeeses(Set employeeses) {
this.employeeses = employeeses;
}
}
従業員:
package com.test.model;
// Generated Apr 7, 2012 7:10:28 PM by Hibernate Tools 3.4.0.CR1
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
* Employees generated by hbm2java
*/
@Entity
@Table(name="Employees"
,catalog="test"
)
public class Employees implements java.io.Serializable {
private Integer id;
private Departments departments;
private String firstName;
private String lastName;
public Employees() {
}
public Employees(Departments departments, String firstName, String lastName) {
this.departments = departments;
this.firstName = firstName;
this.lastName = lastName;
}
@Id @GeneratedValue(strategy=IDENTITY)
@Column(name="Id", unique=true, nullable=false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="DepartmentsId", nullable=false)
public Departments getDepartments() {
return this.departments;
}
public void setDepartments(Departments departments) {
this.departments = departments;
}
@Column(name="FirstName", nullable=false)
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Column(name="LastName", nullable=false)
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
私のアクション クラス (Struts2 XSLT の結果によってシリアル化されます):
package com.test.view;
import java.util.List;
import java.util.Iterator;
import com.opensymphony.xwork2.ActionSupport;
import com.test.controller.DepartmentsManager;
import com.test.model.Departments;
import com.test.util.HibernateUtil;
public class DepartmentsAction extends ActionSupport {
private DepartmentsManager departmentsManager;
private List<Departments> departmentsList;
public DepartmentsAction() {
this.departmentsManager = new DepartmentsManager();
}
public String list() {
this.departmentsList = departmentsManager.list();
System.out.println("Execute called");
HibernateUtil.createDTO(departmentsList);
return SUCCESS;
}
public List<Departments> getDepartmentsList() {
return departmentsList;
}
public void setDepartmentsList(List<Departments> departmentsList) {
this.departmentsList = departmentsList;
}
}
My Manager クラス (部門のリストを作成するために Action クラスが呼び出すクラス):
package com.test.controller;
import java.util.List;
import java.util.Iterator;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import com.test.model.Departments;
import com.test.util.HibernateUtil;
public class DepartmentsManager {
public List<Departments> list() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
List<Departments> set = null;
try {
Query q = session.createQuery("FROM Departments");
/*Query q = session.createQuery("FROM Departments d JOIN FETCH d.employeeses e");*/
q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
set = (List<Departments>) q.list();
} catch (HibernateException e) {
e.printStackTrace();
session.getTransaction().rollback();
}
session.getTransaction().commit();
return set;
}
}