访问集合时Hibernate LazyInitializationException

时间:2012-06-27 12:34:35

标签: spring hibernate jsf

当我想从另一张桌子获取数据时,我得到了以下异常

17:38:45,823 ERROR [org.hibernate.LazyInitializationException] failed to lazily initialize a collection of role: com.sinergia.ea.model.TypeOfArtifactModel.checkedItems, no session or session was closed: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.sinergia.ea.model.TypeOfArtifactModel.checkedItems, no session or session was closed
        at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358) [:3.2.6.ga]
        at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350) [:3.2.6.ga]
        at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343) [:3.2.6.ga]
        at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86) [:3.2.6.ga]
        at org.hibernate.collection.PersistentSet.toString(PersistentSet.java:309) [:3.2.6.ga]
        at java.lang.String.valueOf(String.java:2826) [:1.6.0_18]
        at java.lang.StringBuilder.append(StringBuilder.java:115) [:1.6.0_18]
        at com.sinergia.ea.view.TypeOfArtifactBean.editTypeOfArtifact(TypeOfArtifactBean.java:203) [:]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_18]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [:1.6.0_18]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [:1.6.0_18]
        at java.lang.reflect.Method.invoke(Method.java:597) [:1.6.0_18]
        at org.apache.el.parser.AstValue.invoke(AstValue.java:196) [:6.0.0.Final]
        at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276) [:6.0.0.Final]
        at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) [:2.1.3-SNAPSHOT]
        at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) [:2.1.0-FCS]
        at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) [:2.1.3-SNAPSHOT]
        at javax.faces.component.UICommand.broadcast(UICommand.java:315) [:2.1.0-FCS]
        at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) [:2.1.0-FCS]
        at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) [:2.1.0-FCS]
        at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) [:2.1.3-SNAPSHOT]
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [:2.1.3-SNAPSHOT]
        at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [:2.1.3-SNAPSHOT]
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409) [:2.1.0-FCS]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:324) [:6.0.0.Final]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.0.0.Final]

模特课程:

@Entity
@Table(name="TYPE_OF_ARTIFACT")
public class TypeOfArtifactModel implements java.io.Serializable , Identifiable{

    /**
     * 
     */
    private static final long serialVersionUID = 2662289176706818360L;



    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TYPE_OF_ARTIFACT_SEQ")
    @SequenceGenerator(name = "TYPE_OF_ARTIFACT_SEQ", sequenceName = "TYPE_OF_ARTIFACT_SEQ")
    @Column(name="ID",unique=true, nullable=false)
    private Integer id;

    @Column(name="DESCRIPTION", nullable=true, length=400)
    private String description;

    @Column(name="NAME", nullable=false, length=50)
    private String name;

    @OneToMany(targetEntity = AdditionalInfoModel.class, mappedBy = "typeOfArtifactID",cascade = CascadeType.ALL)
    private Set<AdditionalInfoModel> additionalInfos = new HashSet<AdditionalInfoModel>(0);


    @OneToMany
    @JoinTable(name = "TYPE_ARTIFACT_OPERATE_RELATION", joinColumns = { @JoinColumn(name = "TYPE_OF_ARTIFACT_ID") }, inverseJoinColumns = { @JoinColumn(name = "OPERATE_ARTIFACT_ID") })
    private Set<TypeOfArtifactModel> checkedItems = new HashSet<TypeOfArtifactModel>(0);



    public TypeOfArtifactModel() {
    }

查看bean

public String editTypeOfArtifact() {
        additionalInfoModelList = additionalInfoService.getAdditionalInfoList(getCurrentItem());
        setAdditionalInfoModelList(additionalInfoModelList);
        if(getCurrentItem() != null){
            Set<TypeOfArtifactModel> typeOfArtifactCheckedItems = getCurrentItem().getCheckedItems();
            System.out.println("TypeOfArtifactCheckedItems :"+typeOfArtifactCheckedItems);
            if(typeOfArtifactModelList != null && !(typeOfArtifactModelList.isEmpty())){
                if(typeOfArtifactCheckedItems != null && !(typeOfArtifactCheckedItems.isEmpty())){
                for (TypeOfArtifactModel item : typeOfArtifactModelList) {
                    for (TypeOfArtifactModel checkedItem : typeOfArtifactCheckedItems) {
                        if(item.getId()==checkedItem.getId()){
                            checked.put(checkedItem.getId().longValue(), true);
                        }
                    }
                }
            }
         }
        }

        return null;
    }

设置typeOfArtifactCheckedItems = getCurrentItem()。getCheckedItems();

我在特定情况下遇到上述错误为什么会发生这种情况我不知道请给我一个解决方案。

1 个答案:

答案 0 :(得分:2)

默认情况下,@OneToMany集合例如checkedItems由Hibernate延迟加载。这意味着当您加载TypeOfArtifactModel时,将创建代理以代替实际的集合。

当您第一次访问该集合时,Hibernate将尝试从数据库加载所需的实体。但是,该加载必须使用与原始实体相同的会话。在您的情况下,在尝试访问集合之前,会话似乎已关闭。

要避免这种情况,您需要:

  • 使用FetchType.EAGER(不建议这样做)
  • 使集合急切加载
  • 使用HQL提取连接或使用Hibernate.initialize(model.getCheckedItems())获取TypeOfArtifactModel时获取集合

您尚未展示任何交易管理代码,但请确保在会话关闭(或提交交易)之前执行上述操作。

值得指出的是,每天都会在Stack Overflow上询问一次。