2015-09-28 56 views
0

我使用注释@PersistenceUnit来获取EntityManagerFactory的一个实例,但经过多次测试后,它不起作用。我一直在寻找理论,例子等,但没有成功。理论看起来很简单,但我无法看到我的代码出现问题,或缺少什么。@PersistenceUnit不工作(Java EE 7,Glassfish 4.1)

我使用bean的代码是:

import ... 

@Stateless 
@TransactionManagement(TransactionManagementType.BEAN) 
public class TopBean extends UserTransactionWrapper implements TopService 
{ 

    @Inject 
    Logger logger = LoggerFactory.getLogger(this.getClass()); 

    @PersistenceUnit(unitName="puTop") 
    private EntityManagerFactory entityManagerFactory; 

    @Override 
    public OperationResult<Boolean> retrieve() 
    { 
     return execute(); 
    } 

    protected OperationResult<Boolean> doRetrieve() 
                       throws Exception 
    { 
      OperationResult<Boolean> operationResult = new OperationResult<Boolean>(); 
      EntityManager entityManager = entityManagerFactory.createEntityManager(); 

      long id = 5; 
      Node node = new Node(id, "Host.One", NodeType.SWITCH, true); 
      entityManager.persist(node); 
      operationResult.setData(node.getId() == id); 

      return operationResult; 
    } 

    @Override 
    protected Logger getLogger() 
    { 
     return logger; 
    } 

} 

的UserTransactionWrapper类仅包含初始化由函数获得的用户交易代码:

private UserTransaction getTransaction() 
                    throws NamingException 
{ 
    Context context = new InitialContext(); 
    return (UserTransaction)context.lookup("java:comp/UserTransaction"); 
} 

的用@Resource注入用户事务不起作用,所以我必须这样做。

我的persistence.xml是:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> 
    <persistence-unit name="puTop" transaction-type="JTA"> 
     <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
     <jta-data-source>jdbc/Top</jta-data-source> 
     <class>...</class> 
     <exclude-unlisted-classes>true</exclude-unlisted-classes> 
    </persistence-unit> 
</persistence> 

预先感谢您!

马努

我加入了UserTransactionWrapper类的代码:

public abstract class UserTransactionWrapper extends Wrapper 
{ 

    @SuppressWarnings("unchecked") 
    protected <E> OperationResult<E> execute(Object... parameters) 
    { 
     OperationResult<E> operationResult = new OperationResult<E>(); 
     Method doMethod = findMethod(); 
     Logger logger = getLogger(); 
    // If the method exists... 
     if (doMethod != null) 
     { 
      UserTransaction userTransaction = null; 
      try 
      { 

      // Initializing user transaction 
      // ============================= 

       userTransaction = getTransaction(); 
       userTransaction.begin(); 

      // Accomplishment of the operation 
      // =============================== 

       int parametersN = (parameters != null ? parameters.length : 0); 
       Object[] auxiliary = new Object[parametersN]; 
       for (int i = parametersN; (--i) >= 0;) auxiliary[i] = parameters[i]; 

       doMethod.setAccessible(true); 
       operationResult = (OperationResult<E>)doMethod.invoke(this, auxiliary); 

      // Completion of the transaction 
      // ============================= 

       userTransaction.commit(); 

      } 
      catch (Exception primary) 
      { 
       try 
       { 
       // If transaction is defined... 
        if (userTransaction != null) userTransaction.rollback(); 

        boolean invocationError = primary instanceof InvocationTargetException; 
       // If the invoked method has thrown an exception... 
        if (invocationError) 
        { 
         Throwable cause = primary.getCause(); 
         cause = (cause != null ? cause : primary); 
         operationResult.setError(cause); 
         logger.error(INVOCATION_ERROR, cause); 
        } 
       // If it hasn't done... 
        else 
        { 
         operationResult.setError(primary); 
         logger.error(UNEXPECTED_ERROR, primary); 
        } 
       } 
       catch (Exception secondary) 
       { 
        logger.error(UNEXPECTED_ERROR, secondary); 
       } 
      } 
     } 
    // If it doesn't exist... 
     else 
     { 
      operationResult = new OperationResult<E>(); 
      operationResult.setError(new NoSuchMethodException()); 
     } 

     return operationResult; 
    } 

    private UserTransaction getTransaction() 
                     throws NamingException 
    { 
     Context context = new InitialContext(); 
     return (UserTransaction)context.lookup("java:comp/UserTransaction"); 
    } 

} 

回答

0

我想这个问题是,你正试图注入EntityManagerFactory,但你必须在注入EntityManager代替使用JTA。

更改您的代码看起来像这样:

@PersistenceUnit(unitName="puTop") 
private EntityManager entityManager; 

,并直接使用EntityManager

如果您不是要使用的交易类型“RESOURCE_LOCAL”,然后改变你的persistence.xml以下几点:

<persistence-unit name="puTop" transaction-type="RESOURCE_LOCAL"> 



反正也没有理由这样做手工事务管理。
你可以只写你这样的代码:

@Stateless 
public class TopBean 
{ 
    @PersistenceUnit(unitName="puTop") 
    private EntityManager entityManager; 

    public Node persist() { 

     Node node = new Node(5, "Host.One", NodeType.SWITCH, true); 
     entityManager.persist(node); 
     return node; 
    } 
} 

这就是你需要坚持实体一切......

+0

我想是不是按照理论的解决方案。我测试过了,它不起作用。看到这个[link](http://www.byteslounge.com/tutorials/container-vs-application-managed-entitymanager)。 – Manu

+0

请再次阅读您的链接...您未使用transaction-type =“RESOURCE_LOCAL”。 – unwichtich

+0

如果我正确阅读教程,则使用BMT_的_Valid应用程序托管持久性上下文使用建议代码使用JTA事务类型。 – Manu