{"action":"created","issue":{"url":"https://api.github.com/repos/dropwizard/dropwizard/issues/850","labels_url":"https://api.github.com/repos/dropwizard/dropwizard/issues/850/labels{/name}","comments_url":"https://api.github.com/repos/dropwizard/dropwizard/issues/850/comments","events_url":"https://api.github.com/repos/dropwizard/dropwizard/issues/850/events","html_url":"https://github.com/dropwizard/dropwizard/issues/850","id":54469802,"number":850,"title":"UnitOfWorkApplicationListener.java commits transaction after exception is thrown in a request.","user":{"login":"lhcjackson-toast","id":6314712,"avatar_url":"https://avatars.githubusercontent.com/u/6314712?v=3","gravatar_id":"","url":"https://api.github.com/users/lhcjackson-toast","html_url":"https://github.com/lhcjackson-toast","followers_url":"https://api.github.com/users/lhcjackson-toast/followers","following_url":"https://api.github.com/users/lhcjackson-toast/following{/other_user}","gists_url":"https://api.github.com/users/lhcjackson-toast/gists{/gist_id}","starred_url":"https://api.github.com/users/lhcjackson-toast/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lhcjackson-toast/subscriptions","organizations_url":"https://api.github.com/users/lhcjackson-toast/orgs","repos_url":"https://api.github.com/users/lhcjackson-toast/repos","events_url":"https://api.github.com/users/lhcjackson-toast/events{/privacy}","received_events_url":"https://api.github.com/users/lhcjackson-toast/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-01-15T16:26:54Z","updated_at":"2015-03-04T19:33:23Z","closed_at":null,"body":"I am on 0.8.0-rc2\r\n\r\nAfter an exception is thrown in the request, RESOURCE_METHOD_FINISHED event is dispatched first, then ON_EXCEPTION event is dispatched, so we have two problems with the following code:\r\n1. Transaction is committed when exception is thrown. It should be rolled back.\r\n2. If the commit fails, the original exception is lost, replaced by a database exception.\r\n\r\nMy recommended fix is to check for existing exceptions in RESOURCE_METHOD_FINISHED. \r\n\r\n@Override\r\npublic void onEvent(RequestEvent event) {\r\n    if (event.getType() == RequestEvent.Type.RESOURCE_METHOD_START) {\r\n        this.unitOfWork = this.methodMap.get(event.getUriInfo()\r\n                .getMatchedResourceMethod().getInvocable().getDefinitionMethod());\r\n        if (unitOfWork != null) {\r\n            this.session = this.sessionFactory.openSession();\r\n            try {\r\n                configureSession();\r\n                ManagedSessionContext.bind(this.session);\r\n                beginTransaction();\r\n            } catch (Throwable th) {\r\n                this.session.close();\r\n                this.session = null;\r\n                ManagedSessionContext.unbind(this.sessionFactory);\r\n                throw th;\r\n            }\r\n        }\r\n    }\r\n    else if (event.getType() == RequestEvent.Type.RESOURCE_METHOD_FINISHED) {\r\n        if (this.session != null) {\r\n            try {\r\n                commitTransaction();\r\n            } catch (Exception e) {\r\n                rollbackTransaction();\r\n                this.<RuntimeException>rethrow(e);\r\n            }\r\n            finally {\r\n                this.session.close();\r\n                this.session = null;\r\n                ManagedSessionContext.unbind(this.sessionFactory);\r\n            }\r\n        }\r\n    }\r\n    else if (event.getType() == RequestEvent.Type.ON_EXCEPTION) {\r\n        if (this.session != null) {\r\n            try {\r\n                rollbackTransaction();\r\n            }\r\n            finally {\r\n                this.session.close();\r\n                this.session = null;\r\n                ManagedSessionContext.unbind(this.sessionFactory);\r\n            }\r\n        }\r\n    }\r\n}"},"comment":{"url":"https://api.github.com/repos/dropwizard/dropwizard/issues/comments/77228922","html_url":"https://github.com/dropwizard/dropwizard/issues/850#issuecomment-77228922","issue_url":"https://api.github.com/repos/dropwizard/dropwizard/issues/850","id":77228922,"user":{"login":"phxql","id":700033,"avatar_url":"https://avatars.githubusercontent.com/u/700033?v=3","gravatar_id":"","url":"https://api.github.com/users/phxql","html_url":"https://github.com/phxql","followers_url":"https://api.github.com/users/phxql/followers","following_url":"https://api.github.com/users/phxql/following{/other_user}","gists_url":"https://api.github.com/users/phxql/gists{/gist_id}","starred_url":"https://api.github.com/users/phxql/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/phxql/subscriptions","organizations_url":"https://api.github.com/users/phxql/orgs","repos_url":"https://api.github.com/users/phxql/repos","events_url":"https://api.github.com/users/phxql/events{/privacy}","received_events_url":"https://api.github.com/users/phxql/received_events","type":"User","site_admin":false},"created_at":"2015-03-04T19:33:23Z","updated_at":"2015-03-04T19:33:23Z","body":"The order in which jersey emits the events is:\r\n\r\nIn case of exception:\r\n* MATCHING_START\r\n* REQUEST_MATCHED\r\n* REQUEST_FILTERED\r\n* RESOURCE_METHOD_START\r\n* RESOURCE_METHOD_FINISHED\r\n* ON_EXCEPTION\r\n* EXCEPTION_MAPPER_FOUND\r\n* EXCEPTION_MAPPING_FINISHED\r\n* RESP_FILTERS_START\r\n* RESP_FILTERS_FINISHED\r\n* FINISHED\r\n\r\nIn case of no exception:\r\n* MATCHING_START\r\n* REQUEST_MATCHED\r\n* REQUEST_FILTERED\r\n* RESOURCE_METHOD_START\r\n* RESOURCE_METHOD_FINISHED\r\n* RESP_FILTERS_START\r\n* RESP_FILTERS_FINISHED\r\n* FINISHED\r\n\r\nMy proprosed fix is to replace `RESOURCE_METHOD_FINISHED` with `RESP_FILTERS_START`. With this fix the transaction is rolled back in case of an exception. If no exception happens, the transaction is committed."}}