2013-03-11 62 views
4

我有一个基于Maven的Java EE项目,应该在GlassFish v3上运行。有一个注入EJB服务的JSF ManagedBean。 ManagedBean调用其中一些JPA操作发生时按钮单击的注入EJB方法之一(创建新实体对象,持久化,刷新)。时调用的EntityManager.flush()则抛出异常:Java EE:Eclipselink事务丢失

Caused by: javax.persistence.TransactionRequiredException: Exception 
Description: No transaction is currently active 

数据源是与JTA事务类型(persistence.xml中所定义的)一个JTA数据源。

我已经找到了解决方案,但由于部署问题而不能令人满意。 如果我把代码的下一行成的persistence.xml然后它运行没有任何问题:

<property name="eclipselink.target-server" value="SunAS9"/> 

因为这个原因,我认为它是一个部署问题,当的EclipseLink不承认JTA经理。

任何建议,将不胜感激,谢谢你!

UPDATE:

@MRalwasser:这里是完整的堆栈跟踪。 (对不起,我不得不删除真正的软件包名称,它现在是masked.package.name)stack trace on pastebin

@Chris:对不起,我忘了提及,GeneriDao类通过工厂方法创建实体管理器,而不是依赖注入。

+0

你能向我们展示异常的完整堆栈跟踪吗? – MRalwasser 2013-03-11 17:53:56

+0

除非容器管理持久性单元,以便将所需属性注入到上下文中,否则需要告知EclipseLink如何查找JTA事务管理器和数据源(如果特定于服务器)。即如果使用javax.persistence.Persistence.getEntityManagerFactory而不是注入 – Chris 2013-03-11 20:29:53

+0

为什么不能使用'eclipselink.target-server'?无论是在persistence.xml中,还是在创建时通过属性重写。没有这个属性,我遇到了各种类加载器问题,包括非活动事务。 – Jarekczek 2017-06-13 13:58:24

回答

0

默认情况下,只有EJB可以在CMT中工作。在托管的bean或CDI bean中,您必须实现自己的机制来处理事务并从中运行您的服务。

public class ManagedBean {   

    @Inject 
    yourEjbService service; 

    @Resource 
    UserTransaction utx; 

    public void save(){ 
     try{ 
      utx.begin(); 
      service.doAction(); 
      utx.commit(); 
     } catch (Exception e) { 
      try { 
       utx.rollback(); 
      } catch (Exception ex) { 
       ... 
      } 
     } 
    } 
    ... 
} 

你也不必打电话EntityManager.flush()既不在EJB也不是管理的Bean,如果你正在使用@PersistenceContext注入的EntityManager。它会在您的EJB中的每个方法结束后自动分离实体。

0

Java Enterprise的持久性控制机制有几个选项和特定的设计选择。在我所使用的几乎任何Java EE实现中,都使用了容器管理事务(CMT)。在某种情况下,bean管理事务(BMT)可以作为选择。

Bean管理事务在需要确定的时候,确切地说,在程序执行过程中发生'commit'(或'rollback')时可能是首选。这可能需要在高性能的时间关键应用领域。对于BMT的例子,参见例如在examples, Bean Managed Transactions

集装箱节“Bean管理事务”管理的事务意味着在应用服务器软件(“容器”)调用之前执行的Java代码,使用一个持久化上下文的“开始” transction 。当代码执行完成时(当调用树已经返回时,例如由于web请求),应用程序服务器调用'commit'。因此,修改的实体实际上在应用程序数据库中更新。

在Java EE中,语句:@TransactionManagement(TransactionManagementType.CONTAINER)@TransactionManagement(TransactionManagementType.BEAN)分别指示容器管理事务或Bean管理事务。Java EE 定义了几种类型的bean:会话驱动的bean,消息驱动的bean,本地bean。这些bean通常是@Stateless,并且都可以使用容器管理的事务。

的容器管理的事务处理的详细控制可以在EE可以通过添加注释指定:

@TransactionAttribute(REQUIRES_NEW) 
public void myTopLevelMethodWhichStartsNewInnerTransaction() 
.... 
@TransactionAttribute(REQUIRED) 
public void myTopLevelMethodContinueExistingTransactionIfAny() 
.... 
@TransactionAttribute(NEVER) 
public void myNoCurrentTransactionAllowedWhenMethodCalled() 
.... 

冲洗

调用“齐平”,以确保数据库高速缓存中写入的必要性在磁盘上,取决于所用数据库的类型。例如。对于Postgress调用flush有所影响,而对于内存数据库'derby',冲洗没有效果,并且在后一种情况下会导致类似于此问题中报告的错误。 flush的影响因此取决于数据库。