Hibernate integration¶
Example of dropwizard-hibernate bundle usage with guicey.
Example source code
Configuration¶
Additional dependencies required:
compile 'io.dropwizard:dropwizard-hibernate:1.3.0' compile 'com.h2database:h2:1.4.193'
H2 used as the simplest example.
Overall configuration is exactly the same as described in dropwizard docs, but extracted to separate class for simplicity:
public class HbnBundle extends HibernateBundle<HbnAppConfiguration> { public HbnBundle() { super(Sample.class); } @Override public PooledDataSourceFactory getDataSourceFactory(HbnAppConfiguration configuration) { return configuration.getDataSourceFactory(); } }
Note
All model classes are configured inside the constructor: super(Sample.class);
Configuration class:
public class HbnAppConfiguration extends Configuration { @Valid @NotNull @JsonProperty private DataSourceFactory database = new DataSourceFactory(); public DataSourceFactory getDataSourceFactory() { return database; } }
Configuration file for in-memory database and automatic schema creation:
database: driverClass: org.h2.Driver user: sa password: url: jdbc:h2:mem:sample properties: charSet: UTF-8 hibernate.dialect: org.hibernate.dialect.H2Dialect hibernate.hbm2ddl.auto: create
Guice integration¶
Guice module used to provide SessionFactory instance into guice context:
public class HbnModule extends AbstractModule { private final HbnBundle hbnBundle; public HbnModule(HbnBundle hbnBundle) { this.hbnBundle = hbnBundle; } @Override protected void configure() { bind(SessionFactory.class).toInstance(hbnBundle.getSessionFactory()); } }
Application:
@Override public void initialize(Bootstrap<HbnAppConfiguration> bootstrap) { final HbnBundle hibernate = new HbnBundle(); // register hbn bundle before guice to make sure factory initialized before guice context start bootstrap.addBundle(hibernate); bootstrap.addBundle(GuiceBundle.builder() .enableAutoConfig("com.myapp.package") .modules(new HbnModule(hibernate)) .build()); }
Usage¶
It is simpler to use dropwizard AbstractDAO
for hibernate logic:
public class SampleService extends AbstractDAO<Sample> { @Inject public SampleService(SessionFactory factory) { super(factory); } public void create(Sample sample) { return persist(sample); } public List<Sample> findAll() { return list(currentSession().createQuery("from Sample")); } }
You will need to use dropwizard @UnitOfWork
annotation to declare transaction scope.
For example:
@Path("/sample") @Produces("application/json") public class SampleResource { @Inject private SampleService service; @GET @Path("/") @Timed @UnitOfWork public Response doStaff() { final Sample sample = new Sample("sample"); service.create(sample); final List<Sample> res = service.findAll(); // using response to render entities inside unit of work and avoid lazy load exceptions return Response.ok(res).build(); } }