问题
I'm developing a small REST web server with Jersey and Hibernate. Along the way I've encountered some weird behaviour on behalf of Hibernate. Namely, when trying to Session.save() an object after POST request from curl, the server replies with 500, but I don't see any error in the command window.
But when I toggle a breakpoint and do a step over the cursor runs inside some of the jars in the dependencies, where I eventually track down the error message. Still it doesn't show it anywhere.
How can I force hibernate to show all these errors? Or is it Jersey that needs to be set up?
The method where I toggled a breakpoint:
@POST
@Path("{id}/comments/new")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response handlePostNewComment(@PathParam("id") int taskId, ItemComment newComment) {
newComment.setItemId(taskId);
Session s = HibernateUtil.getSessionFactory().openSession();
Transaction tx = s.beginTransaction();
**Integer newCommentId = (Integer)s.save(newComment);**
s.flush();
tx.commit();
s.close();
HashMap res = new HashMap();
res.put("id", newCommentId);
return Response.status(201).entity(res).build();
}
Server response to curl:
$ curl -i -X POST -H "Content-type: application/json" --data @comm.json localhost:8000/task/19/comments/new
HTTP/1.1 500 Request failed. Content-Type: text/html;charset=ISO-8859-1 Date: Tue, 27 Oct 2015 20:34:16 GMT Connection: close Content-Length: 1033
Message in console in IntelliJ:
Connected to the target VM, address: '127.0.0.1:57501', transport: 'socket'
task tracker enterprise Edition running
Oct 27, 2015 9:34:12 PM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [localhost:8000]
Application started.
Stop the application using CTRL+C
Oct 27, 2015 9:34:12 PM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
Oct 27, 2015 9:34:14 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.0.2.Final}
Oct 27, 2015 9:34:14 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Oct 27, 2015 9:34:14 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Oct 27, 2015 9:34:14 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.0.0.Final}
Oct 27, 2015 9:34:14 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
Oct 27, 2015 9:34:14 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [org.postgresql.Driver] at URL [jdbc:postgresql://localhost:5432/tracker]
Oct 27, 2015 9:34:14 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=cristian, password=****}
Oct 27, 2015 9:34:14 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
Oct 27, 2015 9:34:14 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 1 (min=1)
Oct 27, 2015 9:34:14 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL94Dialect
Oct 27, 2015 9:34:15 PM org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl useContextualLobCreation
INFO: HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
Oct 27, 2015 9:34:15 PM org.hibernate.type.BasicTypeRegistry register
INFO: HHH000270: Type registration [java.util.UUID] overrides previous : org.hibernate.type.UUIDBinaryType@43aa6671
Oct 27, 2015 9:34:15 PM org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService
INFO: HHH000397: Using ASTQueryTranslatorFactory
It looks the same on a successful request, except with some SQL echoed from hibernate.
When debugging I finally come across the exception somewhere in the org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher class
java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
This has happened several times, with different error messages.
What can I do to force these components to show me the error messages, either on stdout or stderr? Or log them somewhere?
回答1:
It's situations like this I just register an ExceptionMapper<Throwable>. These are used to map exceptions to Responses. Sometimes where there is an unhandled exception, Jersey will swallow it, sending the client a sometimes useless 500 Server Error. In these cases the ExceptionMapper will allow use to handle it ourselves, at leasting printing the stacktrace before sending the response
@Provider
public class DebugExceptionMapper implements ExceptionMapper<Throwable> {
@Overrride
public Response toResponse(Throwable e) {
e.printStackTrace();
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
Also See:
- WebApplicationException and Mapping Exceptions to Responses
来源:https://stackoverflow.com/questions/33378255/hibernate-doesnt-throw-exception-or-show-errors