我正在开始一个结合了" 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;
}
}
答案 0 :(得分:1)
按以下方式更改课程:
@Transactional
public class TestManagedBean extends AbstractManagedBean {
您的方法如下:
@Transactional
public String test() {