我正在学习使用JAX-RS进行一些restful api开发,并且我的资源类有一个问题。
我的理解是我的资源类应该是持久化的,然而,当它持久化我对实体管理器的RequestScoped方法的调用时,它抛出了一个TransactionRequiredException。
如果我将我的资源类更改为无状态,那么一切都很好,并且实体管理器可以毫无问题地持久化。
我仍然是JavaEE的新手,我想知道为什么会发生这种情况,以及@Stateless注解如何正确地注入持久化上下文。我还想知道JAX-RS资源类是无状态的,而不是我见过的大多数教程中都有的RequestScoped,这有什么问题吗?
我在下面包含了一些示例代码来说明。
@Path("Things")
//@Stateless //works just fine when em.persist() is called
@RequestScoped //throws transactionrequiredexception when em.persist() is called
public class ThingsResource{
@PersistenceContext(unitName = "persistenceUnitName")
EntityManager em;
public ThingsResource() { }
@POST
@Produces(MediaType.APPLICATION_JSON)
public Response postThing(ThingDTO thing){
ThingEntity newThing = new ThingEntity(thing);
em.persist(newThing);
em.flush();
return Response.created(new URI("/" + newThing.getId()).build();
}
}发布于 2013-12-14 00:04:21
马蒂亚斯说得很对。
@无状态注释bean是一个默认提供Container-Managed-Transactions的EJB。如果EJB的客户端没有提供事务,CMT将默认创建一个新的事务。
Required Attribute如果客户端在事务内运行并调用企业bean的方法,则该方法在客户端的事务内执行。如果客户端未与事务相关联,则容器将在运行该方法之前启动一个新事务。
Required属性是使用容器管理的事务划分运行的所有企业bean方法的隐式事务属性。除非需要覆盖另一个事务属性,否则通常不会设置Required属性。因为事务属性是声明性的,所以以后可以很容易地更改它们。
在最近的jax-rs上的java-ee-7 tuturial中,Oracle有使用EJB的例子(@Stateless)。
...结合使用EJB的@javax.ejb.Asynchronous注释和@Suspended,可以异步执行业务逻辑,并最终通知感兴趣的客户端。任何JAX-RS根资源都可以使用@Stateless或@Singleton注释进行注释,并且实际上可以用作EJB。
在此场景中,@RequestScoped与@Stateless之间的主要区别将是容器可以将EJB池化,并避免一些昂贵的构造/销毁操作,这些操作可能需要用于bean,否则这些bean将在每个请求上构造。
发布于 2015-10-02 14:44:09
当您不想将根资源作为EJB (通过使用@Stateless注释它)时,您可以使用UserTransaction。
@Path("/things")
@RequestScoped
public class ThingsResource{
@POST
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response create(final Thing thing){
utx.begin();
em.joinTransaction();
final ThingEntity thingEntity = new ThingEntity(thing);
em.persist(thing);
utx.commit();
final URI uri = uriInfo.getAbsolutePathBuilder()
.path(Long.toString(thingEntity.getId())).build();
return Response.created(uri).build();
}
@PersistenceContext(unitName = "somePU")
private transient EntityManager em;
@Resource
private transient UserTransaction ut;
@Context
private transient UriInfo uriInfo;
}https://stackoverflow.com/questions/20558125
复制相似问题