這是我對這個問題進行了很多研究後的第一篇文章。使用JSF轉換器時延遲加載異常(引用集合)
這個例子的Jboss 7.1下運行與接縫3.1與接縫管理持久化上下文
我使用實體bean一個轉換器時面臨的一個問題,經典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
(焊料+持久+面)。目標是通過重用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(我試過ConversationScoped後SessionScoped - >同樣的問題)
@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"/>
任何幫助將受到歡迎。
好
<f:attribute name="collectionType" value="java.util.ArrayList" />;
,這一切看起來好像變流器訪問採集前的交易已經被關閉。你確定在這一點上你有交易嗎?注入的EntityManager的範圍是什麼? – 2012-03-27 14:34:49