gpt4 book ai didi

java - 如何避免 Hibernate 中的 LazyInitializationException?

转载 作者:行者123 更新时间:2023-11-30 09:38:16 26 4
gpt4 key购买 nike

我将 Hibernate 用作具有多个外键关系的数据库的 ORM。问题是有时我想获取这些相关的数据集,有时我不想,所以在这些集合上我将“获取”设置为“惰性”。不幸的是,每次我尝试序列化这些对象时,Hibernate 都会抛出 LazyInitializationException,因为 session 已关闭。使用 OpenSessionInView 过滤器只会导致 Hibernate 无论如何都要填充这些集合,从而首先破坏了拥有惰性集合的全部目的。

有没有一种简单的方法可以序列化或提取 POJO 中填充的数据而不触发 LIE,并且不必填充所有惰性集合?

编辑:这是我试图开始工作的一些示例代码,处理两个表,“部门”和“员工”,这是与部门的一对多关系的 child 。我希望能够查看数据库中列出的部门,而不必加载属于所述部门的所有员工:

部门:

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;
}
}

我的经理类(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;
}
}

最佳答案

惰性集合仅在事务范围内工作(从数据库中检索拥有实体的范围)。换句话说,您不应该传递一个 Hibernate 实体,其中包含未加载的惰性子实体或事务范围之外的集合。

如果要将实体传递给 JSP、序列化代码或其他任何内容,则需要构建另一个实体或使用 lazy="false"。

关于java - 如何避免 Hibernate 中的 LazyInitializationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10181584/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com