【发布时间】:2015-01-19 11:42:01
【问题描述】:
我正在启动一个结合“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;
}
}
【问题讨论】: