Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何避免Hibernate中的LazyInitializationException?_Java_Hibernate_Struts2_Persistence - Fatal编程技术网

Java 如何避免Hibernate中的LazyInitializationException?

Java 如何避免Hibernate中的LazyInitializationException?,java,hibernate,struts2,persistence,Java,Hibernate,Struts2,Persistence,我使用Hibernate作为一个数据库的ORM,该数据库有许多外键关系。问题是,有时我想获取这些相关的数据集,有时我不想,所以在这些集合上,我将“fetch”设置为“lazy”。不幸的是,每次我尝试序列化这些对象时,Hibernate都会抛出LazyInitializationException,因为会话已关闭。使用OpenSessionInView过滤器只会导致Hibernate填充这些集合,从而从一开始就破坏了拥有惰性集合的全部目的 有没有一种简单的方法可以序列化或提取POJO中填充的数据,

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

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

编辑:下面是一些我正在尝试使用的示例代码,处理两个表,“Departments”和“Employees”,这两个表是与部门的一对多关系中的子表。我希望能够查看数据库中列出的部门,而不必加载属于所述部门的所有员工:

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.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;
}
}
部门:

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.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;
}
}
My action类(由Struts2 XSLT结果序列化):

package com.test.view;
导入java.util.List;
导入java.util.Iterator;
导入com.opensymphony.xwork2.ActionSupport;
导入com.test.controller.DepartmentsManager;
导入com.test.model.Departments;
导入com.test.util.HibernateUtil;
公共类部门活动扩展了ActionSupport{
私人部门经理部门经理;
私人名单部门名单;
公共部门(){
this.departmentsManager=新的departmentsManager();
}
公共字符串列表(){
this.departmentsList=departmentsManager.list();
System.out.println(“执行调用”);
HibernateUtil.createDTO(部门列表);
回归成功;
}
公共列表getDepartmentsList(){
返回部门列表;
}
公共作废设置部门列表(列出部门列表){
this.departmentsList=部门列表;
}
}
My Manager类(Action类调用该类以填充部门列表):

package com.test.controller;
导入java.util.List;
导入java.util.Iterator;
导入org.hibernate.Criteria;
导入org.hibernate.hibernate;
导入org.hibernate.hibernateeexception;
导入org.hibernate.Query;
导入org.hibernate.Session;
导入com.test.model.Departments;
导入com.test.util.HibernateUtil;
公共类部门经理{
公开名单(){
会话会话=HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
列表集=空;
试一试{
Query q=session.createQuery(“来自部门”);
/*Query q=session.createQuery(“从部门d加入获取d.employeeses e”)*/
q、 setResultTransformer(标准:不同的根实体);
set=(List)q.List();
}捕获(休眠异常e){
e、 printStackTrace();
session.getTransaction().rollback();
}
session.getTransaction().commit();
返回集;
}
}

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


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

管理视图中延迟加载的两种简单方法:

  • 使用事务视图(包括将视图调用包装到JTA事务中(例如,由应用程序管理)

  • 在bean中使用一个扩展的持久性上下文,并在处理完它后显式地刷新它,这意味着一旦能够加载惰性对象

有关更多信息,请查看此帖子及其答案:


OSIV是正确的方法。听起来好像“无论如何”都在填充集合因为您正在使用它们,所以需要填充它们。实际上,我没有使用它们。问题是整个对象都会传递到Struts2 xslt结果对象中,该对象会尽职尽责地遍历该对象,并尝试将所有内容解析为XML。只要它尝试序列化和解析延迟加载的集合(还没有加载,因为我现在不需要它),Hibernate抛出了一个异常。如果Hibernate只返回“null”并让解析器继续处理它的事务,那将更有帮助。这听起来像是传递了一个中间对象(表示您实际想要序列化的实体的视图)使用Struts是一种不太难闻的方法。这样做有意义吗?如果没有,我可以尝试在回答中详细说明。(对此我有点怀疑,因为我对Struts2 XSLT结果对象完全不熟悉。)是的,这很有意义,除了传递Hibernate对象本身之外,这将是我的首选方法。问题是,如何创建中间对象?我需要某种方法来检查实体的各种延迟加载集合,以查看它们是否已填充,这样我就可以添加已填充的集合,并保留e其他人,都没有触发LazyInitializationException。不,对不起,没有可以-不喜欢那样。你可能可以(使用
try/catch(LazyInitializationException)
但那很难闻)。我的意思是:为您希望呈现的每个视图创建一个单独的类;因此,可能的视图集是在编译时固定和确定的,而不是在运行时。Eugene,构建另一个实体的最简单方法是什么,省去未加载的集合?任何时候您尝试直接访问集合以查看它是否存在,Hibernate将引发延迟初始化异常。执行此操作的最佳方法是什么?1.构建实体副本应在transactio内部完成