Hibernate integration

Example of dropwizard-hibernate bundle usage with guicey.

Example source code

Configuration

Additional dependencies required:

    implementation 'io.dropwizard:dropwizard-hibernate:2.0.2'
    implementation 'com.h2database:h2:1.4.199'

Note

Both versions are managed by BOM

For simplicity, an embedded H2 database is used.

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();
    }
}