Provides a Unit of Work annotation for a Jdbi backed Dropwizard service for wrapping resource methods in a transaction context
-
Dropwizardprovides a very slick@UnitOfWorkannotation that wraps a transaction context around resource methods annotated with this annotation. This is very useful for wrapping multiple calls in a single database transaction all of which will succeed or roll back atomically. -
However, this support is only available for
Hibernate. For all the goodnessJdbibrings, we had to bring the transactionality on our own. This module provides support forJdbiUnitOfWorkwith aJdbibackend
This project is available on Maven Central. To add it to your project you can add the following dependency to your
pom.xml:
<dependency>
<groupId>com.github.isopropylcyanide</groupId>
<artifactId>dropwizard-jdbi-unitofwork</artifactId>
<version>1.2</version>
</dependency>
transactionalityacross multiple datasources when called from a request threadtransactionalityacross multiple datasources acrossmultiple threadsexcludingselectively, certain set of URI's from transaction contexts, such asELB,Health ChecksetcHttp GETmethods are excluded from transaction by default.Http POSTmethods are wrapped around in a transaction only when annotated with@JdbiUnitOfWork
-
Add the dependency to your
pom.xml -
Construct a
JdbiUnitOfWorkProviderfrom the DBI instance.JdbiUnitOfWorkProvider provider = JdbiUnitOfWorkProvider.withDefault(dbi); // most common or JdbiUnitOfWorkProvider provider = JdbiUnitOfWorkProvider.withLinked(dbi);
If you are using Guice, you can bind the instance
bind(JdbiUnitOfWorkProvider.class).toInstance(provider);
-
Provide the list of package where the SQL Objects / DAO (to be attached) are located. Classes with Jdbi annotations
@SqlQueryor@SqlUpdateor@SqlBatchor@SqlCallwill be picked automatically.
Use
JdbiUnitOfWorkProviderto generate the proxies. You can also register the classes one by one.// class level SampleDao dao = (SampleDao) provider.getWrappedInstanceForDaoClass(SampleDao.class); // use the proxies and pass it as they were normal instances resource = new SampleResource(dao); // package level List<String> daoPackages = Lists.newArrayList("<fq-package-name>", "fq-package-name-2", ...); Map<? extends Class, Object> proxies = unitOfWorkProvider.getWrappedInstanceForDaoPackage(daoPackages); // use the proxies and pass it as they were normal instances resource = ...new SampleResource((SampleDao)proxies.get(SampleDao.class))
- Finally, we need to register the event listener with the Jersey Environment using the constructed provider
In case you'd like to exclude certain URI paths from being monitored, you can pass them into exclude paths;
environment.jersey().register(new JdbiUnitOfWorkApplicationEventListener(provider, new HashSet<>()));;Set<String> excludePaths = new HashSet<>(); environment.jersey().register(new JdbiUnitOfWorkApplicationEventListener(handleManager, excludePaths));
- Start annotating resource methods with
@JdbiUnitOfWorkand you're good to go.@POST @Path("/") @JdbiUnitOfWork public RequestResponse createRequest() { ..do stateful work (across multiple Dao's) return response }
- This library relies on
Jersey Monitoring Eventsto bind request lifecycle with a transaction aspect - At the backend, all
Jdbiobjects such asDaoorSqlObjectsare proxied behind aJdbiHandleManager JdbiHandleManagercontract specifies thegetandclearof the actual handles to the calling thread.
Please file bug reports and feature requests in GitHub issues.
Copyright (c) 2020-2023 Aman Garg
This library is licensed under the Apache License, Version 2.0.
See http://www.apache.org/licenses/LICENSE-2.0.html or the LICENSE file in this repository for the full license text.
