为什么我通过从 bean 调用 @Stateless 方法来获得 TransactionRequiredException?

问题描述

环境:

  • JBoss 7.2
  • Java 11

我正在尝试通过 TestBean 控制器从 JSF 页面数据库插入数据,但是我收到一条错误消息,指出 javax.persistence.TransactionrequiredException 我需要一个事务。 插入方法()在@Stateless ConsultaService 中,所以我认为它认是事务性的,但看起来有些错误

代码是从 JBoss 5.2 迁移的,但我没有问题,当我调用 insert method() 时,创建的事务没有任何问题。这在 JBoss 7.2 中是否有所改变?

我应该为每个方法添加@Transactional 吗?还是我遗漏了其他东西?

**TestBean.java **

@Named
@ViewScoped
public class TestBean implements Serializable {

    ...
    
    @Inject
    ConsultaServiceable consultaSvc;

    ...
    public void insert() {
        try {
            Consulta consulta1 = new Consulta();
            consulta1.setConsulta("hola");
            consulta1.setCognom1("cognom");
            consulta1.setCp("07000");
            consulta1.trace();
            consultaSvc.insert(consulta);//ERROR TransactionrequiredException
        } catch (AppException e) {
            log.error("error inserting consulta",e);
        }
    }
    ...
}

BusinessServiceable.java

public interface BusinessServiceable<T> extends QueryServiceable<T> {
    T insert(T entity) throws AppException;
    T update(T entity) throws AppException;
    void remove(T entity) throws AppException;
}

QueryService.java

public abstract class QueryService<T> extends Queryable implements QueryServiceable<T> {
    
    @PersistenceContext(unitName = "bdPU")
    protected EntityManager eManager;

    protected Class<T> entityClass;

    ...

    public QueryService(Class<T> entityClass) {
        this.entityClass = entityClass;
    }
    ...
}

BusinessService.java

public abstract class BusinessService<T> extends QueryService<T> implements BusinessServiceable<T> {

    ...
    @PermitAll
    public T insert(T entity) throws AppException {

        try {
            eManager.persist(entity);
        } catch (Exception e) {
            log.error("Error on BusinessService.insert ",e);

            Throwable t = e.getCause();

            if (t instanceof org.hibernate.exception.ConstraintViolationException) {
                throw new AppException("Error on BusinessService.insert " + entity.getClass().getSimpleName() + " id " + entity.toString(),e);
            } else {
                throw new AppException("Error on insert",e);
            }
        }

        return entity;
    }
    ...
}

ConsultaService.java

@Stateless
@Local
@PermitAll
public class ConsultaService extends BusinessService<Consulta> implements ConsultaServiceable {

    public ConsultaService() {
        super(Consulta.class);
    }

    @PermitAll
    @Override
    public Consulta insert(Consulta entity) throws AppException {
        return super.insert(entity);
    }
    ...
}

错误服务器日志

10:46:52,329 ERROR [es.caib.accfor.business.QueryService] (default task-1) Error on BusinessService.insert : javax.persistence.TransactionrequiredException: WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context)
    at org.jboss.as.jpa@7.2.0.GA-redhat-00005//org.jboss.as.jpa.container.AbstractEntityManager.transactionIsrequired(AbstractEntityManager.java:877)
    at org.jboss.as.jpa@7.2.0.GA-redhat-00005//org.jboss.as.jpa.container.AbstractEntityManager.persist(AbstractEntityManager.java:579)
    at deployment.accfor2.ear//es.caib.accfor.business.BusinessService.insert(BusinessService.java:43)
    at deployment.accfor2.ear//es.caib.accfor.business.consulta.boundary.ConsultaService.insert(ConsultaService.java:46)
    at deployment.accfor2.ear//es.caib.accfor.business.consulta.boundary.ConsultaService$Proxy$_$$_WeldSubclass.insert(UnkNown Source)
    at deployment.accfor2.ear//es.caib.accfor.business.consulta.boundary.ConsultaService.insert(ConsultaService.java:14)
    at deployment.accfor2.ear.accfor-front.war//es.caib.accfor.presentation.front.TestBean.insert(TestBean.java:57)

解决方法

这是 pom.xml 依赖项和 ejb 模块的问题。