Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.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
Spring Hibernate的lazyinitializationexception异常_Spring_Hibernate - Fatal编程技术网

Spring Hibernate的lazyinitializationexception异常

Spring Hibernate的lazyinitializationexception异常,spring,hibernate,Spring,Hibernate,我在项目中使用数据库中实体的延迟初始化。作为JPA实现,我使用Hibernate。但当我需要在自定义JSP上获取实体集合时,我会得到一个lazyinitializationexception,因为Hibernate会话已经关闭。请告诉我是否有可能在不使用特殊请求的情况下防止此异常,如中所述。以下是我的一些代码: @Entity public class Statistic extends EntityAbstract { private static final long serial

我在项目中使用数据库中实体的延迟初始化。作为JPA实现,我使用Hibernate。但当我需要在自定义JSP上获取实体集合时,我会得到一个lazyinitializationexception,因为Hibernate会话已经关闭。请告诉我是否有可能在不使用特殊请求的情况下防止此异常,如中所述。以下是我的一些代码:

@Entity
public class Statistic extends EntityAbstract {

    private static final long serialVersionUID = -6372957177860305322L;
    @Temporal(TemporalType.TIMESTAMP)
    private Date date;
    private boolean correct;

    @ManyToOne(fetch = FetchType.LAZY, cascade = {MERGE, PERSIST, REFRESH, DETACH})
    @JoinColumn(name = "questionId", nullable = false)
    private Question question;

    @ManyToOne(fetch = FetchType.LAZY, cascade = {MERGE, PERSIST, REFRESH, DETACH})
    @JoinColumn(name = "userId", nullable = false)
    private User user;

    public Statistic() {
    }

    public Statistic(Date date, boolean correct, Question question, User user) {
        this.date = date;
        this.correct = correct;
        this.question = question;
        this.user = user;
    }

    getter... setter...
}

@Entity
public class Question extends EntityAbstract {

    private static final long serialVersionUID = -2751224412459986012L;
    private String description;

    @ManyToOne(fetch = FetchType.LAZY, cascade = {MERGE, PERSIST, REFRESH, DETACH})
    @JoinColumn(name = "testId", nullable = false)
    private Test test;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "question")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Set<Answer> answers;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "question")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Set<Literature> literature;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "question")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Set<Statistic> statistics;

    public Question() {
    }

    public Question(String description, Test test) {
        this.description = description;
        this.test = test;
    }

    getter... setter...
}

@Entity
public class Literature extends EntityAbstract {

    private static final long serialVersionUID = 218407080623072886L;
    private String description;

    @ManyToOne(fetch = FetchType.LAZY, cascade = {MERGE, PERSIST, REFRESH, DETACH})
    @JoinColumn(name = "questionId", nullable = false)
    private Question question;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "literature")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Set<Link> links;

    public Literature() {
    }

    public Literature(String description, Question question) {
        this.description = description;
        this.question = question;
    }

    getter... setter...
}

@Entity
public class Link extends EntityAbstract {

    private static final long serialVersionUID = 6494218299043499655L;
    private String link;

    @ManyToOne(fetch = FetchType.LAZY, cascade = {MERGE, PERSIST, REFRESH, DETACH})
    @JoinColumn(name = "literatureId", nullable = false)
    private Literature literature;

    public Link() {
    }

    public Link(String link, Literature literature) {
        this.link = link;
        this.literature = literature;
    }

    getter... setter...
}

And I need to get a collection of questions from statistics and further along the chain. I use this service:

@Repository
@Transactional
public interface CrudRepository<T extends EntityAbstract> {

    SessionFactory getBeanToBeAutowired();

    // create
    @SuppressWarnings("unchecked")
    default T add(T entity){
        return (T) getBeanToBeAutowired().getCurrentSession().merge(entity);
    }

    // read
    @SuppressWarnings("unchecked")
    default T getById(Class<T> entityClass, long id){
        return (T)getBeanToBeAutowired().getCurrentSession().find(entityClass, id);
    }

    // update
    @SuppressWarnings("unchecked")
    default T update(T entity){
        return (T) getBeanToBeAutowired().getCurrentSession().merge(entity);
    }

    // delete
    default void delete(T entity){
        getBeanToBeAutowired().getCurrentSession().remove(entity);
    }

    @SuppressWarnings("unchecked")
    default List<T> getAll(Class<T> t){
        return (List<T>)getBeanToBeAutowired()
                .getCurrentSession()
                .createQuery("FROM " + t.getSimpleName())
                .list();
    }
}

public interface StatisticRepository extends CrudRepository<Statistic> {
}

public interface StatisticService extends StatisticRepository {

    Statistic getById(long id);
    List<Statistic> getAll();
}

@Service("statisticService")
public class StatisticServiceImpl implements StatisticService {

    private SessionFactory sessionFactory;

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public SessionFactory getBeanToBeAutowired() {
        return sessionFactory;
    }

    @Override
    public Statistic getById(long id) {
        return getById(Statistic.class, id);
    }

    @Override
    public List<Statistic> getAll() {
        return getAll(Statistic.class);
    }
}
@实体
公共类统计扩展了EntityAbstract{
私有静态最终长serialVersionUID=-6372957177860305322L;
@时态(TemporalType.TIMESTAMP)
私人日期;
私有布尔正确;
@manytone(fetch=FetchType.LAZY,cascade={MERGE,PERSIST,REFRESH,DETACH})
@JoinColumn(name=“questionId”,null=false)
私人问题;
@manytone(fetch=FetchType.LAZY,cascade={MERGE,PERSIST,REFRESH,DETACH})
@JoinColumn(name=“userId”,nullable=false)
私人用户;
公共统计(){
}
公共统计(日期、布尔值正确、问题、用户){
this.date=日期;
this.correct=正确;
这个问题=问题;
this.user=用户;
}
盖特…塞特。。。
}
@实体
公共类问题扩展实体抽象{
私有静态最终长serialVersionUID=-2751224412459986012L;
私有字符串描述;
@manytone(fetch=FetchType.LAZY,cascade={MERGE,PERSIST,REFRESH,DETACH})
@JoinColumn(name=“testId”,nullable=false)
私人测试;
@OneToMany(fetch=FetchType.LAZY,mappedBy=“question”)
@OnDelete(action=OnDeleteAction.CASCADE)
私人设定答案;
@OneToMany(fetch=FetchType.LAZY,mappedBy=“question”)
@OnDelete(action=OnDeleteAction.CASCADE)
私家文学;
@OneToMany(fetch=FetchType.LAZY,mappedBy=“question”)
@OnDelete(action=OnDeleteAction.CASCADE)
私有集统计;
公众问题({
}
公开问题(字符串描述、测试){
this.description=描述;
这个。测试=测试;
}
盖特…塞特。。。
}
@实体
公共类文献扩展了实体抽象{
私有静态最终长serialVersionUID=218407080623072886;
私有字符串描述;
@manytone(fetch=FetchType.LAZY,cascade={MERGE,PERSIST,REFRESH,DETACH})
@JoinColumn(name=“questionId”,null=false)
私人问题;
@OneToMany(fetch=FetchType.LAZY,mappedBy=“文学”)
@OnDelete(action=OnDeleteAction.CASCADE)
专用集链接;
公共文学(){
}
公共文献(字符串描述、问题){
this.description=描述;
这个问题=问题;
}
盖特…塞特。。。
}
@实体
公共类链接扩展了EntityAbstract{
私有静态最终长serialVersionUID=649421829904349655L;
私有字符串链接;
@manytone(fetch=FetchType.LAZY,cascade={MERGE,PERSIST,REFRESH,DETACH})
@JoinColumn(name=“literatureId”,nullable=false)
私人文学;
公共链接(){
}
公共链接(字符串链接、文献){
this.link=link;
文学=文学;
}
盖特…塞特。。。
}
我需要从统计数据中收集问题,并进一步沿着这条链。我使用这项服务:
@存储库
@交易的
公共接口存储{
SessionFactory GetBeantobauToWired();
//创造
@抑制警告(“未选中”)
默认T添加(T实体){
返回(T)getBeantobautowired().getCurrentSession().merge(实体);
}
//阅读
@抑制警告(“未选中”)
默认T getById(类entityClass,长id){
返回(T)getBeantobautowired().getCurrentSession().find(entityClass,id);
}
//更新
@抑制警告(“未选中”)
默认T更新(T实体){
返回(T)getBeantobautowired().getCurrentSession().merge(实体);
}
//删除
默认无效删除(T实体){
GetBeanToBeautWired().getCurrentSession().remove(实体);
}
@抑制警告(“未选中”)
默认列表getAll(t类){
return(List)getbeantobautowired()
.getCurrentSession()
.createQuery(“来自”+t.getSimpleName())
.list();
}
}
公共接口StatisticRepository扩展了Crudepository{
}
公共接口StatisticService扩展了StatisticRepository{
统计getById(长id);
List getAll();
}
@服务(“统计服务”)
公共类StatisticServiceImpl实现StatisticService{
私人会话工厂会话工厂;
@自动连线
public void setSessionFactory(SessionFactory SessionFactory){
this.sessionFactory=sessionFactory;
}
@凌驾
public SessionFactory getBeantobautowired(){
返回工厂;
}
@凌驾
公共统计getById(长id){
返回getById(Statistic.class,id);
}
@凌驾
公共列表getAll(){
返回getAll(Statistic.class);
}
}

我解决了以下问题(在这里使用本文):

@NamedEntityGraph(
name=“graph.statistic”,
attributeNodes=@NamedAttributeNode(value=“question”,subgraph=“questionGraph”),
子图={
@NamedSubgraph(name=“questionGraph”,
attributeNodes=@NamedAttributeNode(value=“文学”,subgraph=“文学图形”),
@NamedSubgraph(name=“文学图形”,
attributeNodes=@NamedAttributeNode(value=“links”)}
)
@实体
公共类统计扩展了EntityAbstract{
私有静态最终长serialVersionUID=-6372957177860305322L;
@时态(TemporalType.TIMESTAMP)
私人日期;
私有布尔正确;
@manytone(fetch=FetchType.LAZY,ca
@NamedEntityGraph(
        name = "graph.statistic",
        attributeNodes = @NamedAttributeNode(value = "question", subgraph = "questionGraph"),
        subgraphs = {
                @NamedSubgraph(name = "questionGraph",
                        attributeNodes = @NamedAttributeNode(value = "literature", subgraph = "literatureGraph")),
                @NamedSubgraph(name = "literatureGraph",
                        attributeNodes = @NamedAttributeNode(value = "links"))}
)
@Entity
public class Statistic extends EntityAbstract {

    private static final long serialVersionUID = -6372957177860305322L;
    @Temporal(TemporalType.TIMESTAMP)
    private Date date;
    private boolean correct;

    @ManyToOne(fetch = FetchType.LAZY, cascade = {MERGE, PERSIST, REFRESH, DETACH})
    @JoinColumn(name = "questionId", nullable = false)
    private Question question;

    @ManyToOne(fetch = FetchType.LAZY, cascade = {MERGE, PERSIST, REFRESH, DETACH})
    @JoinColumn(name = "userId", nullable = false)
    private User user;

    public Statistic() {
    }

    public Statistic(Date date, boolean correct, Question question, User user) {
        this.date = date;
        this.correct = correct;
        this.question = question;
        this.user = user;
    }

    getters... and setters..... 
}

@Service("statisticService")
public class StatisticServiceImpl implements StatisticService {

 ...

    @Override
    @Transactional
    public List<Statistic> getUserStatisticByUserIdAndDate(long id, Date startDate, Date endDate) {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        RootGraph<?> graph = session.getEntityGraph("graph.statistic");
        List<Statistic> statistics = session
                .createQuery("FROM Statistic WHERE user.id = :id AND date between :startDate AND :endDate", Statistic.class)
                .setParameter("id", id)
                .setParameter("startDate", startDate)
                .setParameter("endDate", endDate)
                .setHint("javax.persistence.fetchgraph", graph)
                .getResultList();
        session.getTransaction().commit();
        session.close();
        return statistics;
}