org.hibernate.LazyInitializationException:懒得初始化角色集合:没有会话或会话被关闭

时间:2017-10-30 13:30:34

标签: java hibernate

我指定我的实体如下

 package com.drishti.training.dbentity;

import java.util.List;

import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Table;

import com.drishti.dacx.core.framework.ameyoentitytypes.AbstractDBEntity;

/**
 *
 */
@Entity
@Table(name = "template")
public class TemplateDBEntity extends AbstractDBEntity {

    String template_name, organisationId;

    @Column(name = "organisation_id", nullable = false)
    public String getOrganisationId() {
        return organisationId;
    }

    public void setOrganisationId(String organisationId) {
        this.organisationId = organisationId;
    }

    private String templateId;
    //    private List<Integer> listOfTrainingIds;

    private List<String> listOfTrainingIds;

    @Id
    @Column(name = "template_id", nullable = false)
    public String getTemplateId() {
        return templateId;
    }

    public void setTemplateId(String templateId) {
        this.templateId = templateId;
    }

    @ElementCollection(targetClass = String.class)
    @CollectionTable(name = "template_id_vs_training_id", joinColumns = @JoinColumn(name = "template_id"))
    @Column(name = "training_id", nullable = false)
    public List<String> getListOfTrainingIds() {
        return listOfTrainingIds;
    }

    public void setListOfTrainingIds(List<String> listOfTrainingIds) {
        this.listOfTrainingIds = listOfTrainingIds;
    }

    @Column(name = "template_name")
    public String getName() {
        return template_name;
    }

    public void setName(String name) {
        this.template_name = name;
    }
}

另一张表是

create table template_id_vs_training_id
(
    template_id varchar references template(template_id) on delete cascade,
    training_id varchar references training(training_id) on delete cascade,
    PRIMARY KEY (template_id,training_id)
);

但是当我加载TemplateDBEntity时它会向我提供上面报告的错误。

1 个答案:

答案 0 :(得分:4)

https://github.com/zeit/pkg,正如hibernate文档所说:

  

表示尝试访问a之外的尚未获取的数据   会话上下文。例如,当未初始化的代理或   会话结束后访问集合

此异常的唯一原因是listOfTrainingIds属性,因为它是一个 LazyInitializationException默认情况下加载了Lazy,因此:

  • 确保您在交易中访问listOfTrainingIds属性(您的实体可以使用可用的会话来获取您的收藏)。

  • 或者让它急切@ElementCollection(fetch = FetchType.EAGER),但请注意,每次从数据库中选择实体时,即使您不需要,您的收藏品也会热切地加载,这会影响表现。

  • 或者在您的休眠查询中使用@ElementCollection关键字(如果您使用查询加载实体):

    List<TemplateDBEntity> TemplateDBEntitys = session.createQuery(
    "select t from TemplateDBEntity t join fetch t.listOfTrainingIds", 
    TemplateDBEntity.class).getResultList();
    // In class...
    @FetchProfile(
      name = "withListOfTrainingIds",
      fetchOverrides = {@FetchProfile.FetchOverride(mode = FetchMode.JOIN, association = "listOfTrainingIds", entity = TemplateDBEntity.class)})
    public class TemplateDBEntity extends AbstractDBEntity {
      //...
    }

    // To get your entity
    session.enableFetchProfile("withListOfTrainingIds");
    System.out.println(session.get(TemplateDBEntity.class, templateId));
    session.disableFetchProfile("withListOfTrainingIds");

我更喜欢最后两个选项,因为hibernate会对数据库执行一次查询,即使你保持加载延迟,这对于性能更好。