This user guide is for version 0.9.3-1. Javadoc is available, as are guides for other versions.
Getting Started
If you’re using Maven, simply add the dropwizard-entitymanager
dependency to your POM:
<dependency>
<groupId>com.scottescue</groupId>
<artifactId>dropwizard-entitymanager</artifactId>
<version>0.9.3-1</version>
</dependency>
Configuration
First, your configuration class needs a DataSourceFactory
instance:
public class ExampleConfiguration extends Configuration {
@Valid
@NotNull
private DataSourceFactory database = new DataSourceFactory();
@JsonProperty("database")
public DataSourceFactory getDataSourceFactory() {
return database;
}
}
Then, add an EntityManagerBundle instance to your application class, specifying your entity classes and how to get a
DataSourceFactory
from your configuration subclass:
private final EntityManagerBundle<ExampleConfiguration> entityManagerBundle =
new EntityManagerBundle<ExampleConfiguration>(Person.class) {
@Override
public DataSourceFactory getDataSourceFactory(ExampleConfiguration configuration) {
return configuration.getDataSourceFactory();
}
};
@Override
public void initialize(Bootstrap<ExampleConfiguration> bootstrap) {
bootstrap.addBundle(entityManagerBundle);
}
@Override
public void run(ExampleConfiguration config, Environment environment) {
final EntityManager entityManager = entityManagerBundle.getSharedEntityManager();
environment.jersey().register(new UserResource(entityManager));
}
If you don’t want to explicitly specify your entity classes, you can instead create a ScanningEntityManagerBundle instance specifying a package in your application to recursively scan for entity classes:
private final EntityManagerBundle<ExampleConfiguration> entityManagerBundle =
new ScanningEntityManagerBundle<ExampleConfiguration>("com.myapp") {
@Override
public DataSourceFactory getDataSourceFactory(ExampleConfiguration configuration) {
return configuration.getDataSourceFactory();
}
};
Creating an instance of either type of bundle will create a new managed connection pool to the database, a health check
for connectivity to the database, and a new EntityManagerFactory
as well as a thread-safe EntityManager
instance
for you to use in your classes.
Usage
Container Managed Persistence for Resource Methods
The shared EntityManager obtained from your EntityManagerBundle works with the @UnitOfWork annotation.
The @UnitOfWork annotation may be applied to resource methods to create a container managed PersistenceContext. This
gives you the ability to declaratively scope transaction boundaries.
@POST
@Timed
@UnitOfWork
public Response create(@Valid Person person) {
entityManager.persist(checkNotNull(person));
return Response.created(UriBuilder.fromResource(PersonResource.class)
.build(person.getId()))
.build();
}
This will automatically initialize the EntityManager
, begin a transaction, call persist, commit the transaction, and
finally close the EntityManager
. If an exception is thrown, the transaction is rolled back.
Often you simply need to read data without requiring an actual transaction.
@GET
@Timed
@UnitOfWork(transactional = false)
public Person findPerson(@PathParam("id") LongParam id) {
return entityManager.find(Person.class, id.get());
}
This will automatically initialize the EntityManager
, call find, and finally close the EntityManager
.
javax.persistence.PersistenceException
will be thrown when you attempt
to use the shared EntityManager.
LazyInitializationException
thrown in your template (or null values produced by Jackson).
Container Managed Persistence Outside Jersey Resources
Currently creating transactions with the @UnitOfWork annotation works out-of-box only for resources managed by
Jersey. If you want to use it outside Jersey resources, e.g. in services, you should instantiate your class with
UnitOfWorkAwareProxyFactory
. If you had a simple PersonService including a @UnitOfWork annotated method:
public class PersonService {
private final EntityManager entityManager;
public PersonService(EntityManager entityManager) {
this.entityManager = entityManager;
}
@UnitOfWork
public void create(Person person) {
entityManager.persist(person);
}
}
You would create an instance of that service using a UnitOfWorkAwareProxyFactory
:
UnitOfWorkAwareProxyFactory proxyFactory = new UnitOfWorkAwareProxyFactory(entityManagerBundle);
PersonService personService = proxyFactory.create(
PersonService.class,
EntityManager.class,
entityManagerBundle.getSharedEntityManager());
This will create a proxy of your class, which will initialize the shared EntityManager
around
methods with the @UnitOfWork annotation. A transaction will also be created around annotated methods unless the
annotation specifies otherwise.
Application Managed Persistence
There may be times when you need to have more control over the PersistenceContext
or need to manage a new transaction.
The EntityManagerFactory
obtained from your EntityManagerBundle
allows you to create and manage new
EntityManager
instances. Any EntityManager
created from the factory will have a new PersistenceContext
that must be managed by your application.
public void create(Person person) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
try {
transaction.begin();
entityManager.persist(person);
transaction.commit();
} catch (RuntimeException e) {
if (transaction.isActive()) {
transaction.rollback();
}
} finally {
entityManager.close();
}
}
Prepended Comments
By default, dropwizard-entitymanager
configures Hibernate JPA to prepend a comment describing the context of all
queries:
/* load com.example.helloworld.core.Person */
select
person0_.id as id0_0_,
person0_.fullName as fullName0_0_,
person0_.jobTitle as jobTitle0_0_
from people person0_
where person0_.id=?
This will allow you to quickly determine the origin of any slow or misbehaving queries. See the Database - autoCommentsEnabled attribute in the Dropwizard Configuration Reference
Support
Please file bug reports and feature requests in GitHub issues.
Credits
This module is heavily derived from Dropwizard Hibernate. Those who have contributed to Dropwizard Hibernate deserve
much of the credit for this project. I’ve essentially adapted their work to create and expose the EntityManager
and
EntityManagerFactory
objects.
Dropwizard is developed by Coda Hale; Yammer, Inc.; and the Dropwizard Team, licensed under the Apache 2.0 license.
License
Copyright 2015-2016 Scott Escue
This library is licensed under the Apache License, Version 2.0. See the project’s LICENSE file for the full license text.