0

当我想从另一个表中获取数据时出现以下异常

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() {
    }

看豆

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();

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

4

1 回答 1

2

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

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

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

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

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

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

于 2012-06-27T13:07:17.120 回答