I am creating a simple RESTful service
@Path("/book")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Stateless
public class RestBookService {
@PersistenceContext(unitName="bookPU")
private EntityManager em;
@Context
protected UriInfo uriInfo;
@POST
public Response createBook(Book book) {
if (book == null)
throw new BadRequestException();
em.persist(book);
URI bookUri = uriInfo.getAbsolutePathBuilder().path(book.getId() + "").build();
return Response.created(bookUri).build();
}
}
The Book is simple JPA entity
@Entity
@XmlRootElement
public class Book {
static Logger log = Logger.getLogger(Book.class.getName());
public static final String FIND_ALL = "Book.find_all";
@Id
@GeneratedValue
private int id;
@Column(nullable=false)
private String title;
@Column
private Float price;
}
//Just giving a relevant code. There are getters/setters and the constructor
I am deploying the service using Maven on Glassfish 4.1 I am using Jersey Container 2.13 Hibernate 4.3.5 Final Mysql 5.1
and when I try to create a book using cURL as follows
curl -X POST --data-binary "<book><price>12.5</price><title>Book Title</title></book>" -H "Content-Type: application/xml" http://localhost:8080/book-service/rs/book -v
It is throwing following exception.
StandardWrapperValve[jersey-serlvet]: Servlet.service() for servlet jersey-serlvet threw exception
java.lang.IllegalStateException: Not inside a request scope.
at jersey.repackaged.com.google.common.base.Preconditions.checkState(Preconditions.java:149)
at org.glassfish.jersey.process.internal.RequestScope.current(RequestScope.java:228)
at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:156)
at org.jvnet.hk2.internal.MethodInterceptorImpl.invoke(MethodInterceptorImpl.java:74)
at org.jvnet.hk2.internal.MethodInterceptorInvocationHandler.invoke(MethodInterceptorInvocationHandler.java:62)
at com.sun.proxy.$Proxy239.getAbsolutePathBuilder(Unknown Source)
at com.services.bookrestservice.rest.RestBookService.createBook(RestBookService.java:44)
[There is another question similar to this but I have done exactly the same which is given in the answer still I am getting the exception. Also, I have gone through https://java.net/jira/browse/JERSEY-2241 but it seems to be in resolved state with the resolution as cannot reproduce. ]
Can somebody please help me.
EDIT1
I have changed from Stateless annotation to RequestScoped annotation as suggested by @HankCa. It is throwing following exception now.
'javax.persistence.TransactionRequiredException
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.doTxRequiredCheck(EntityManagerWrapper.java:161)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.doTransactionScopedTxCheck(EntityManagerWrapper.java:151)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.persist(EntityManagerWrapper.java:281)
at com.services.bookrestservice.rest.RestBookService.createBook(RestBookService.java:44)
'
Not sure why this exception because it is already in persistentcontext.
EDIT2
@HankCa suggested I did the following change.
Removed
@Context
protected UriInfo uriInfo;
And updated the method signature as
@POST
public Response createBook(Book book, @Context UriInfo uriInfo) {
And the service is working as expected. Thanks HankCa for your help.
Yes I stared at this one for far too long and my solution was as you found at Why is my Jersey JAX-RS server throwing a IllegalStateException about not being in RequestScope?. This was a year ago and I haven't hit it again (though I have been out of EJB land for a while) so I'll give it my best shot.
Specifically I would make these mods:
@RequestScoped
@Context UriInfo uriInfo
in the method or class. In the end i seemed to have gone in the method like:This is code (and this is a line to separate the list from the code so the code shows as code!)
I hope that helps!
Cheers,
bbos