snowdrop-zen / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
1 stars 0 forks source link

Panache REST resource returns 500 - Internal Server Error for violated primary key constraints #249

Closed snowdrop-bot closed 3 years ago

snowdrop-bot commented 3 years ago

Describe the bug Having a JPA entity with a natural ID, when performing an HTTP POST that violates the primary key, a 500 error is returned along with the internal stacktrace.

Expected behavior The REST resource should handle violated primary key constraint errors and return a different HTTP code (409 - Conflict may be a good choice)

Actual behavior The following output is displayed:

ᐅ http POST localhost:8080/category name=foo3 description=bar2

HTTP/1.1 500 Internal Server Error
content-length: 10911
content-type: application/json; charset=utf-8

{
    "details": "Error handling 5ebf531b-4dc5-425a-94d3-08ea0a3791a2-2, org.jboss.resteasy.spi.UnhandledException: io.quarkus.arc.ArcUndeclaredThrowableException: Error invoking subclass method",
    "stack": "org.jboss.resteasy.spi.UnhandledException: io.quarkus.arc.ArcUndeclaredThrowableException: Error invoking subclass method\n\tat org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:106)\n\tat org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:372)\n\tat org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:218)\n\tat org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:519)\n\tat org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261)\n\tat org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)\n\tat org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)\n\tat org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)\n\tat org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)\n\tat io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)\n\tat io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:138)\n\tat io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:41)\n\tat io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:93)\n\tat io.quarkus.runtime.CleanableExecutor$CleaningRunnable.run(CleanableExecutor.java:231)\n\tat java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)\n\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)\n\tat org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2415)\n\tat org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)\n\tat org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)\n\tat org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)\n\tat java.base/java.lang.Thread.run(Thread.java:834)\n\tat org.jboss.threads.JBossThread.run(JBossThread.java:501)\nCaused by: io.quarkus.arc.ArcUndeclaredThrowableException: Error invoking subclass method\n\tat io.quarkus.registry.model.CategoryResourceJaxRs_859b58f732cd417fbbdc8447499c65f578415fa6_Subclass.add(CategoryResourceJaxRs_859b58f732cd417fbbdc8447499c65f578415fa6_Subclass.zig:484)\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:566)\n\tat org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:170)\n\tat org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:643)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:507)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:457)\n\tat org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:459)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:419)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:393)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:68)\n\tat org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:492)\n\t... 18 more\nCaused by: javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.\n\tat com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1307)\n\tat com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:126)\n\tat io.quarkus.narayana.jta.runtime.CDIDelegatingTransactionManager.commit(CDIDelegatingTransactionManager.java:97)\n\tat io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.endTransaction(TransactionalInterceptorBase.java:312)\n\tat io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:160)\n\tat io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:100)\n\tat io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.doIntercept(TransactionalInterceptorRequired.java:32)\n\tat io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.intercept(TransactionalInterceptorBase.java:53)\n\tat io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.intercept(TransactionalInterceptorRequired.java:26)\n\tat io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired_Bean.intercept(TransactionalInterceptorRequired_Bean.zig:340)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)\n\tat io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)\n\tat io.quarkus.registry.model.CategoryResourceJaxRs_859b58f732cd417fbbdc8447499c65f578415fa6_Subclass.add(CategoryResourceJaxRs_859b58f732cd417fbbdc8447499c65f578415fa6_Subclass.zig:462)\n\t... 33 more\nCaused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement\n\tat org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)\n\tat org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)\n\tat org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)\n\tat org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1366)\n\tat org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:453)\n\tat org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3212)\n\tat org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2380)\n\tat org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447)\n\tat org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.beforeCompletion(JtaTransactionCoordinatorImpl.java:355)\n\tat org.hibernate.resource.transaction.backend.jta.internal.synchronization.SynchronizationCallbackCoordinatorNonTrackingImpl.beforeCompletion(SynchronizationCallbackCoordinatorNonTrackingImpl.java:47)\n\tat org.hibernate.resource.transaction.backend.jta.internal.synchronization.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:37)\n\tat com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:76)\n\tat com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:360)\n\tat com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:91)\n\tat com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:162)\n\tat com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1295)\n\t... 46 more\nCaused by: org.hibernate.exception.ConstraintViolationException: could not execute statement\n\tat org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:109)\n\tat org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)\n\tat org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)\n\tat org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)\n\tat org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)\n\tat org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3302)\n\tat org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3829)\n\tat org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:107)\n\tat org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)\n\tat org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478)\n\tat java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)\n\tat org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)\n\tat org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348)\n\tat org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)\n\tat org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)\n\tat org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1362)\n\t... 58 more\nCaused by: org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: \"PRIMARY_KEY_3 ON PUBLIC.CATEGORY(NAME) VALUES ('foo3', 1)\"; SQL statement:\ninsert into Category (createdAt, description, name) values (?, ?, ?) [23505-197]\n\tat org.h2.message.DbException.getJdbcSQLException(DbException.java:357)\n\tat org.h2.message.DbException.get(DbException.java:179)\n\tat org.h2.message.DbException.get(DbException.java:155)\n\tat org.h2.index.BaseIndex.getDuplicateKeyException(BaseIndex.java:101)\n\tat org.h2.mvstore.db.MVSecondaryIndex.requireUnique(MVSecondaryIndex.java:236)\n\tat org.h2.mvstore.db.MVSecondaryIndex.add(MVSecondaryIndex.java:202)\n\tat org.h2.mvstore.db.MVTable.addRow(MVTable.java:732)\n\tat org.h2.command.dml.Insert.insertRows(Insert.java:182)\n\tat org.h2.command.dml.Insert.update(Insert.java:134)\n\tat org.h2.command.CommandContainer.update(CommandContainer.java:102)\n\tat org.h2.command.Command.executeUpdate(Command.java:261)\n\tat org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:199)\n\tat org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:153)\n\tat io.agroal.pool.wrapper.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:86)\n\tat org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)\n\t... 69 more"
}

To Reproduce

Reproducer project here:

category-crud.zip

Once the application is running, open a Terminal and run the following command twice:

http POST localhost:8080/category name=foo description=bar

And you should see the error above.

Environment (please complete the following information):


https://github.com/quarkusio/quarkus/issues/14281


$upstream:14281$