JAX-RS + JPA 中的实体锁定问题
Entity locking issue in JAX-RS + JPA
我已经部署了一个 REST JSON API,在 WildFly 10 上使用 JAX-RS (RESTeasy) 和 JPA (Hibernate) 用 Java 编写。
有时,POST 之后的 GET 需要几分钟才能完成,我在日志中得到几个 warnings/errors。
这是一些代码:
@Stateless
@Path("/articles")
public class ArticleResource {
@PersistenceContext
private EntityManager em;
@POST
@Consumes("application/json")
public Response post(Article article) {
this.em.persist(article);
URI location = UriBuilder.fromUri("/articles/{id}").build(article.getId());
return Response.created(location).build();
}
@GET
@Path("/{id}")
@Produces("application/json")
public Article get(@PathParam("id") Long id) {
return this.em.find(Article.class, id);
}
}
那么,如果我这样做:
$ curl -i -X POST --data @article.json http://localhost/articles
我立即得到这个输出:
HTTP/1.1 201 Created
...
Location: http://localhost/articles/123
如果我立即发出 curl http://localhost/articles/123
,有时 需要 4-6 分钟才能 return JSON,并且在日志中我看到这个:
ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (EJB default - 4)
IJ031012: Unable to obtain lock in 60 seconds: org.jboss.jca.adapters.jdbc.local.LocalManagedConnection
首先:为什么它试图为 SELECT
获取锁?我猜想在调用EntityManager.find
方法之前请求了锁,那么如何注释ArticleResource.get
方法来指示容器不请求锁?
其次:为什么在提交 POST
响应时未释放锁定(我想这是由先前的 POST
请求设置的)?
嗯,我不知道,但我没想到 @Stateless
会话 bean 会被 rest 服务直接使用。从我看到的所有 wildfly 示例中,我希望看到 @Stateless
会话 bean 注入到 REST 服务中。参见:
MemberResourceRESTService.java
此外,请记住,我习惯看到的示例是 Java EE/JPA 示例,如引用的示例,而不是 Hibernate 示例。但是,我知道他们正在努力弃用 Hibernate API 并转向 JPA api.
我已经部署了一个 REST JSON API,在 WildFly 10 上使用 JAX-RS (RESTeasy) 和 JPA (Hibernate) 用 Java 编写。
有时,POST 之后的 GET 需要几分钟才能完成,我在日志中得到几个 warnings/errors。
这是一些代码:
@Stateless
@Path("/articles")
public class ArticleResource {
@PersistenceContext
private EntityManager em;
@POST
@Consumes("application/json")
public Response post(Article article) {
this.em.persist(article);
URI location = UriBuilder.fromUri("/articles/{id}").build(article.getId());
return Response.created(location).build();
}
@GET
@Path("/{id}")
@Produces("application/json")
public Article get(@PathParam("id") Long id) {
return this.em.find(Article.class, id);
}
}
那么,如果我这样做:
$ curl -i -X POST --data @article.json http://localhost/articles
我立即得到这个输出:
HTTP/1.1 201 Created
...
Location: http://localhost/articles/123
如果我立即发出 curl http://localhost/articles/123
,有时 需要 4-6 分钟才能 return JSON,并且在日志中我看到这个:
ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (EJB default - 4)
IJ031012: Unable to obtain lock in 60 seconds: org.jboss.jca.adapters.jdbc.local.LocalManagedConnection
首先:为什么它试图为 SELECT
获取锁?我猜想在调用EntityManager.find
方法之前请求了锁,那么如何注释ArticleResource.get
方法来指示容器不请求锁?
其次:为什么在提交 POST
响应时未释放锁定(我想这是由先前的 POST
请求设置的)?
嗯,我不知道,但我没想到 @Stateless
会话 bean 会被 rest 服务直接使用。从我看到的所有 wildfly 示例中,我希望看到 @Stateless
会话 bean 注入到 REST 服务中。参见:
MemberResourceRESTService.java
此外,请记住,我习惯看到的示例是 Java EE/JPA 示例,如引用的示例,而不是 Hibernate 示例。但是,我知道他们正在努力弃用 Hibernate API 并转向 JPA api.