在项目JSF + EJB + CDI + JAX-RS + GlassFish 4.1上回滚ManagedBean

时间:2015-01-19 11:42:01

标签: jsf glassfish ejb cdi jta

我正在开始一个结合了" JSF + EJB + CDI + JAX-RS + GlassFish 4.1"

的项目

在阅读了一些书籍并进行了一些研究之后,我设法将这些技术完美地融合在一起。除交易控制外,一切正常。

为了帮助理解问题,我创建了一个测试项目https://github.com/douglasjunior/TestRollbackJsfEjbCdiRest

问题是:在ManagedBean中,没有运行抛出异常时回滚事务。

但JAX-RS资源中的相同问题完美无缺。

在我的示例中,我试图在数据库中插入重复记录。我应该在哪里收到DuplicatedKey异常。因此,应该颠倒事务,不应在数据库中插入任何内容。

但是当在ManagedBean中完成此操作时,该异常不会回滚事务。第一条记录已经提交。

GenericDao.java

@Stateless
public class GenericDao implements Serializable {

    @PersistenceContext(unitName = "PU")
    private EntityManager em;

    public void persist(Object entity) {
        getEntityManager().persist(entity);
        getEntityManager().flush();
    }
}

User.java

@Entity
@Table(name = "table_user")
@XmlRootElement
public class User extends AbstractEntity<Long> {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(length = 100, unique = true)
    private String someText;

}

TestManagedBean.java (回滚不起作用)

@Named(value = "testManagedBean")
@ViewScoped
@TransactionManagement(TransactionManagementType.CONTAINER) // I tested also as BEAN
public class TestManagedBean extends AbstractManagedBean {

    @Inject
    private GenericDao dao;

    private User user;

    public TestManagedBean() {
        user = new User();
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED) // I tested also as REQUIRES_NEW
    public String test() {
        if (user.getSomeText() == null || user.getSomeText().isEmpty()) {
            sendErrorMessage("Text is riquired!");
            return null;
        }
        dao.persist(user);
        User user2 = new User();
        user2.setSomeText(user.getSomeText()); // "someText" is unique on database
        dao.persist(user2); // org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "table_user_sometext_key"
        return null;
    }

    public User getUser() {
        return user;
    }    
}

TestResource.java (回滚正常)

@Path("test")
@Stateless
public class TestResource {

    @Inject
    private GenericDao dao;

    @Context
    private UriInfo context;

    public TestResource() {
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public User getTeste(@QueryParam("someText") String someText) {
        if (someText == null || someText.isEmpty()) {
            throw new WebApplicationException("Text is riquired!", Response.Status.BAD_REQUEST);
        }
        System.out.println("someText: " + someText);
        User user = new User();
        user.setSomeText(someText);
        dao.persist(user);
        User user2 = new User();
        user2.setSomeText(user.getSomeText()); // "someText" is unique on database
        dao.persist(user2); // org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "table_user_sometext_key"
        return user;
    }
}

1 个答案:

答案 0 :(得分:1)

按以下方式更改课程:

@Transactional 
public class TestManagedBean extends AbstractManagedBean {

您的方法如下:

@Transactional
public String test() {