首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@Stateless vs @RequestScoped

@Stateless vs @RequestScoped
EN

Stack Overflow用户
提问于 2013-12-13 10:34:29
回答 2查看 21.9K关注 0票数 22

我正在学习使用JAX-RS进行一些restful api开发,并且我的资源类有一个问题。

我的理解是我的资源类应该是持久化的,然而,当它持久化我对实体管理器的RequestScoped方法的调用时,它抛出了一个TransactionRequiredException。

如果我将我的资源类更改为无状态,那么一切都很好,并且实体管理器可以毫无问题地持久化。

我仍然是JavaEE的新手,我想知道为什么会发生这种情况,以及@Stateless注解如何正确地注入持久化上下文。我还想知道JAX-RS资源类是无状态的,而不是我见过的大多数教程中都有的RequestScoped,这有什么问题吗?

我在下面包含了一些示例代码来说明。

代码语言:javascript
复制
@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();

    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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将在每个请求上构造。

票数 15
EN

Stack Overflow用户

发布于 2015-10-02 14:44:09

当您不想将根资源作为EJB (通过使用@Stateless注释它)时,您可以使用UserTransaction

代码语言:javascript
复制
@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;
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20558125

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档