I have successfully used two EntityManager objects pointed to two different DB's.
In the case of transaction propagation via one SFSB method calling another one (in my case
in the same SFSB), an XA datasource may be required to ensure the distributed transaction
is supported.
Gavin's suggestion:
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4064581#...
I'm getting the exception due to the transaction attribute type settings (defaults to
REQUIRED). It happens in different configurations (see test code below).
I have found a workaround, see this thread:
http://forum.java.sun.com/thread.jspa?messageID=10025073
but I will definitely look into SMPC and there's some good info in the last chapter of
the JPA + Hibernate book by Bauer and King. Basically configuration stuff in
components.xml that I was not aware of. Hopefully I can configure two SMPC's to
replace my existing two JPA PersistenceContext EntityManager objects.
The main question is on page 813 of the JPA/Hibernate book, is it possible to configure
multiple ManagedPersistenceContext (component tag) classes pointing to different
EMF's?
testPeerXA.xhtml:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
| <ui:composition
xmlns="http://www.w3.org/1999/xhtml"
|
xmlns:s="http://jboss.com/products/seam/taglib"
|
xmlns:ui="http://java.sun.com/jsf/facelets"
|
xmlns:f="http://java.sun.com/jsf/core"
|
xmlns:h="http://java.sun.com/jsf/html"
|
xmlns:rich="http://richfaces.ajax4jsf.org/rich"
|
xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
|
xmlns:c="http://java.sun.com/jstl/core"
| template="layout/template.xhtml">
|
|
|
| <ui:define name="mainContent">
|
| <h:messages styleClass="message"/>
|
| <rich:panel>
| <h:form id="peerForm">
| <h:selectOneMenu id="selectPeer"
value="#{peerAction.peer}">
| <f:selectItems value="#{peerAction.peersXA}" />
| </h:selectOneMenu>
| <h:outputText value="#{peerAction.employeeId}"/>
| </h:form>
| </rich:panel>
|
|
| </ui:define>
| </ui:composition>
testPeer.xhtml:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
| <ui:composition
xmlns="http://www.w3.org/1999/xhtml"
|
xmlns:s="http://jboss.com/products/seam/taglib"
|
xmlns:ui="http://java.sun.com/jsf/facelets"
|
xmlns:f="http://java.sun.com/jsf/core"
|
xmlns:h="http://java.sun.com/jsf/html"
|
xmlns:rich="http://richfaces.ajax4jsf.org/rich"
|
xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
|
xmlns:c="http://java.sun.com/jstl/core"
| template="layout/template.xhtml">
|
|
|
| <ui:define name="mainContent">
|
| <h:messages styleClass="message"/>
|
| <rich:panel>
| <h:form id="peerForm">
| <h:selectOneMenu id="selectPeer"
value="#{peerAction.peer}">
| <f:selectItems value="#{peerAction.peers}" />
| </h:selectOneMenu>
| <h:outputText value="#{peerAction.employeeId}"/>
| </h:form>
| </rich:panel>
|
|
| </ui:define>
| </ui:composition>
SFSB:
package com.cox.beans.session;
|
| import java.util.List;
| import java.util.ListIterator;
| import java.util.Map;
| import java.util.TreeMap;
|
| import javax.ejb.Remove;
| import javax.ejb.Stateful;
| import javax.ejb.TransactionAttribute;
| import javax.ejb.TransactionAttributeType;
| import javax.persistence.EntityManager;
| import javax.persistence.PersistenceContext;
| import javax.persistence.PersistenceContextType;
|
| import org.jboss.seam.annotations.Destroy;
| import org.jboss.seam.annotations.In;
| import org.jboss.seam.annotations.Logger;
| import org.jboss.seam.annotations.Name;
| import org.jboss.seam.annotations.Out;
| import org.jboss.seam.log.Log;
| import org.jboss.seam.security.Identity;
|
| import com.cox.beans.entity.User;
|
| @Stateful
| @Name("peerAction")
| public class PeerAction implements PeerLocal {
|
| @PersistenceContext(unitName="coxIMDatasource",
type=PersistenceContextType.EXTENDED)
| private EntityManager emCoxIM;
|
| @PersistenceContext(unitName="boIcomsSecurityAudit",
type=PersistenceContextType.EXTENDED)
| private EntityManager emICOMS;
|
| @Logger
| private Log log;
|
| @In
| private Identity identity;
|
| private String networkId = "";
|
| private String peer = "";
|
| @Out
| private List peerList;
|
| @Remove @Destroy
| public void destroy() {
|
| }
| public String getPeer() {
| return "test";
| }
|
| public void setPeer(String peer) {
| this.peer = peer;
| }
|
| //results for testPeer.xhtml...
|
| /*got org.jboss.util.NestedSQLException: Could not enlist in transaction on entering
meta-aware object!;
| when getPeers and getEmployeeId were both annotated with
@TransactionAttribute(TransactionAttributeType.REQUIRED)
|
| works fine if getPeers set to REQUIRES_NEW and getEmployeeId set to REQUIRES_NEW
|
| works fine if getPeers set to REQUIRED and getEmployeeId set to REQUIRES_NEW
|
| works fine with:
|
| @TransactionAttribute(TransactionAttributeType.REQUIRED)
| public Map<String, Integer> getPeers() {
|
| @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
| public Integer getEmployeeId() { */
|
|
//*************************************************************************************************************
|
| //results for testPeerXA.xhtml...
|
| /* got org.jboss.util.NestedSQLException: Could not enlist in transaction on entering
meta-aware object!;
| when getPeersXA set to REQUIRED and getEmployeeId set to REQUIRES_NEW
|
| got org.jboss.resource.JBossResourceException: Could not enlist in transaction on
entering meta-aware object!;
| when getPeersXA set to REQUIRES_NEW and getEmployeeId set to REQUIRES_NEW
|
| got org.jboss.resource.JBossResourceException: Could not enlist in transaction on
entering meta-aware object!;
| when getPeersXA set to REQUIRES_NEW and getEmployeeId set to REQUIRED
|
| got org.jboss.resource.JBossResourceException: Could not enlist in transaction on
entering meta-aware object!;
| with below config:
| @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
| public Map<String, Integer> getPeersXA() {
|
| @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
| public Integer getEmployeeId()
|
| below worked fine:
| @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
| public Map<String, Integer> getPeersXA() {
|
| @TransactionAttribute(TransactionAttributeType.REQUIRED)
| public Integer getEmployeeId() {
|
| */
|
| @TransactionAttribute(TransactionAttributeType.REQUIRED)
| public Map<String, Integer> getPeers() {
|
| long employeeId = 900050881;
|
| Map<String,Integer> map = new TreeMap<String,Integer>();
|
| peerList = emCoxIM.createQuery("SELECT user1 "+
| "FROM User user1 "+
| "WHERE user1.hierarchyPath in "+
| "(SELECT user2.hierarchyPath "+
| "FROM User user2 "+
| "WHERE user2.employeeId = :employeeId) "+
| "ORDER BY user1.firstName ASC")
| .setParameter("employeeId", employeeId)
| .getResultList();
|
| log.info("in getPeerList(): peerList.size() = " + peerList.size());
|
| ListIterator it = peerList.listIterator();
| while(it.hasNext()) {
| User user = (User)it.next();
| map.put(user.getFirstName()+ " " + user.getLastName(),
user.getEmployeeId().intValue());
| }
|
| return map;
| }
|
| @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
| public Map<String, Integer> getPeersXA() {
|
| long employeeId = getEmployeeId();
|
| Map<String,Integer> map = new TreeMap<String,Integer>();
|
| peerList = emCoxIM.createQuery("SELECT user1 "+
| "FROM User user1 "+
| "WHERE user1.hierarchyPath in "+
| "(SELECT user2.hierarchyPath "+
| "FROM User user2 "+
| "WHERE user2.employeeId = :employeeId) "+
| "ORDER BY user1.firstName ASC")
| .setParameter("employeeId", employeeId)
| .getResultList();
|
| log.info("in getPeerList(): peerList.size() = " + peerList.size());
|
| ListIterator it = peerList.listIterator();
| while(it.hasNext()) {
| User user = (User)it.next();
| map.put(user.getFirstName()+ " " + user.getLastName(),
user.getEmployeeId().intValue());
| }
|
| return map;
| }
|
|
|
| @TransactionAttribute(TransactionAttributeType.REQUIRED)
| public Integer getEmployeeId() {
| String networkId = getNetworkId()==null?"":getNetworkId();
|
| List myList = emICOMS.createQuery("from User u where u.networkId =
:networkId").setParameter("networkId", networkId).getResultList();
| User newUser = (User)myList.get(0);
|
| Integer employeeId = newUser.getEmployeeId().intValue();
|
| return employeeId;
| }
|
| private String getNetworkId() {
| if (networkId.equals(""))
| return identity.getUsername();
| else
| return networkId;
| }
|
| }
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4114422#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...