3

これは、この問題について多くの研究を行った後の私の最初の投稿です。

この例は、シーム3.1(はんだ+永続性+面)を備えたJboss 7.1で実行され、シーム管理された永続性コンテキストを備えています

failed to lazily initialize a collection, no session or session was closed: org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closedエンティティBeanでコンバータを使用する場合の古典的な問題に直面しています。目的は、JPAモデルを再利用することにより、100%オブジェクト指向を維持することです。

Beans.xmlで、org.jboss.seam.transaction.TransactionInterceptorアクティブ化されます

エンティティBean:

@Entity
public class Member implements Serializable {

    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private String email;

    @Column(name = "phone_number")
    private String phoneNumber;

    @ManyToMany
    private List<Statut> listeStatut = new ArrayList<Statut>();

    // getters, setters, hashcode, equals
}

@Entity
public class Statut implements Serializable {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @ManyToMany(mappedBy="listeStatut")
    private List<Member> members = new ArrayList<Member>();

    // getters, setters, hashcode, equals
}

JSFページ:

<h:form>
    <h:selectManyCheckbox id="stat" value="#{memberModif.member.listeStatut}">
        <f:converter converterId="statutConverter"/>
        <f:selectItems value="#{memberModif.statutsPossibles}" var="statut" itemValue="#{statut}" itemLabel="#{statut.name}" />
    </h:selectManyCheckbox>


    <h:commandLink id="register" action="#{memberModif.modifier()}" value="Modifier">
        <f:param name="cid" value="#{javax.enterprise.context.conversation.id}"/>
    </h:commandLink>
</h:form>

バッキングBean(SessionScopedの後にConversationScopedで試しました->同じ問題)

@ConversationScoped
@Named
public class MemberModif implements Serializable {

    private static final long serialVersionUID = -291355942822086126L;

    @Inject
    private Logger log;

    @Inject
    private EntityManager em;

    @Inject Conversation conversation;

    private Member member;

    @SuppressWarnings("unused")
    @PostConstruct
    private void init() {
        if (conversation.isTransient()) {
            conversation.begin();
        }
    }

    public String modifier() {
        em.merge(member);
    }

    public Member getMember() {
        if (member == null) {
            member = em.createQuery("from Member m where m.id=:id",Member.class).setParameter("id", new Long(0)).getSingleResult();
        }
        return member;
    }

    public List<Statut> getStatutsPossibles() {
        return em.createQuery("from Statut", Statut.class).getResultList();
    }
}

そしてコンバーター(縫い目に強く影響を受けていObjectConverterます):

@FacesConverter("statutConverter")
public class StatutConverter implements Converter, Serializable {

    final private Map<String, Statut> converterMap = new HashMap<String, Statut>();
    final private Map<Statut, String> reverseConverterMap = new HashMap<Statut, String>();

    @Inject
    private transient Conversation conversation;

    private final transient Logger log = Logger.getLogger(StatutConverter.class);

    private int incrementor = 1;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (this.conversation.isTransient()) {
            log.warn("Conversion attempted without a long running conversation");
        }

        return this.converterMap.get(value);
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (this.conversation.isTransient()) {
            log.warn("Conversion attempted without a long running conversation");
        }

        if (this.reverseConverterMap.containsKey(value)) {
            return this.reverseConverterMap.get(value);
        } else {
            final String incrementorStringValue = String.valueOf(this.incrementor++);
            this.converterMap.put(incrementorStringValue, (Statut)value);
            this.reverseConverterMap.put( (Statut)value, incrementorStringValue);
            return incrementorStringValue;
        }
    }
}

シームの実装をネットで検索しないように、このコンバーターをここに配置しましたが、<s:objectConverter/>タグの代わりにタグを使用するのと同じであることに注意してください。<f:converter converterId="statutConverter"/>

どんな助けでも喜んでいただければ幸いです。

4

2 に答える 2

1

同じトランザクションでオブジェクトにアクセスする必要があります。すでにそれを行っていることが確実な場合は、注入するのではなく、コンテキストで検索してエンティティマネージャーを取得してみてください。私はそのように解決された同様の問題を抱えていました。コレクションへの参照を最初に取得したときに、トランザクションでコレクションを初期化することもできます。

Hibernate.initialize(yourCollection);  
于 2012-07-08T04:38:30.030 に答える
1

これを見てください: selectManyCheckbox LazyInitializationException on process validation

試してみてください <f:attribute name="collectionType" value="java.util.ArrayList" />; :<h:selectManyCheckbox>

于 2014-02-05T21:02:42.040 に答える