0

环境

应用服务器:JBoss AS7 (7.1.1 Final)

JPA 实现:EclipseLink (2.4.1)

操作系统:Windows 7 数据库:PostgreSQL 8.4

更新2,解决了

问题是我实例化了 AccountService 类,而不是使用@EJB. 修复该 EntityManager 在服务中被正确感染并且在执行时事务可用em.persist(account);

更新

我做了一个最小的项目来显示我的问题。发布到 Github:

https://github.com/gotling/jboss-eclipselink-problem

我有两个可能相关的问题,因为我不理解 EJB 的正确使用。

  1. 我无法在持久性 JAR 中将 EnityManager 注入 AccountService.java,从而导致 NullPointerException。

  2. 如果在构造函数中将 EntityManager 发送到 AccountService,则在执行 em.persist 时找不到事务。

项目结构

EJB

  • 库/persistanceunit.jar

  • 网络服务.war

问题

我试图让 JBoss 管理我的 Java EE 服务中的事务。问题是 EclipseLink 在尝试持久化实体时似乎没有获取 JBoss 管理的事务。

我已按照指南https://community.jboss.org/wiki/HowToUseEclipseLinkWithAS7(备选方案 1 和备选方案 2 第 4 步)了解如何使用 EclipseLink 配置 JBoss。

设置

战争

实体管理器像这样在 web-service.war 中注入:

@WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
    @PersistenceContext(unitName="foo")
    EntityManager em;

    public void notify(Notify notify) {
        AccountService accountService = new AccountService(em);
        accountService.create(notify);
    }
}

在上面的类和服务类之间实际上有一个控制器类,其中对 Account 对象进行了转换,将其删除以缩短代码。

持久性单元

实体是这样创建的

persistanceunit.jar 中的 AccountService.java

@Stateless
public class AccountService {
    private EntityManager em;

    public AccountService(EntityManager em) {
        this.em = em;
    }

    public void create(Account account) {
        em.persist(account);
    }
}

堆栈跟踪

当调用应该持久化 Account 实体的 WS 时,我在em.persist(account); 上得到一个异常;

... Caused by: javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context) at org.jboss.as.jpa.container.AbstractEntityManager.transactionIsRequired(AbstractEntityManager.java:692) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final] at org.jboss.as.jpa.container.AbstractEntityManager.persist(AbstractEntityManager.java:562) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final] at se.magos.service.AccountService.create(AccountService.java:50) [persistenceunit-0.0.1-SNAPSHOT.jar:]

问题

  1. 我已启用跟踪日志记录。id.au.ringerc.as7.eclipselinkpersistence不应该在日志中可见吗?

  2. 是否有可能以某种方式将 EntityManager 注入persistanceunit.jar 内的服务类中?

  3. 这应该在哪个 JBoss / EclipseLink 版本中开箱即用?

4

2 回答 2

2

您应该使用 注释 bean@TransactionManagement(TransactionManagementType.CONTAINER)和注释create方法@TransactionAttribute(TransactionAttributeType.REQUIRED)。第一个注解是为了让应用服务器知道事务是由容器管理的,后者是为了让方法启动一个事务,如果没有当前的事务,只要它被调用。

于 2012-11-14T13:45:41.677 回答
1

问题是 AccountService 类是实例化的,而不是使用@EJB注释注入的。修复 EntityManager 后,在服务中正确注入,并且在执行 em.persist(account); 时事务可用;

@WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
    @PersistenceContext(unitName="foo")
    EntityManager em;

    public void notify(Notify notify) {
        AccountService accountService = new AccountService(em);
        accountService.create(notify);
    }
}

@WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
    @PersistenceContext(unitName="foo")
    EntityManager em;

    @EJB
    AccountService accountService;

    public void notify(Notify notify) {
        accountService.create(notify);
    }
}
于 2012-11-19T07:36:28.373 回答