Skip to content

Instantly share code, notes, and snippets.

@Sch3lp
Last active August 29, 2015 13:56
Show Gist options
  • Save Sch3lp/9185192 to your computer and use it in GitHub Desktop.
Save Sch3lp/9185192 to your computer and use it in GitHub Desktop.
Dropwizard-hibernate integration test using a Rule
package org.yourcompany.test;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.context.internal.ManagedSessionContext;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.yammer.dropwizard.config.ConfigurationException;
import com.yammer.dropwizard.config.ConfigurationFactory;
import com.yammer.dropwizard.db.DatabaseConfiguration;
import com.yammer.dropwizard.db.ManagedDataSource;
import com.yammer.dropwizard.db.ManagedDataSourceFactory;
import com.yammer.dropwizard.validation.Validator;
public class DropwizardHibernateRule implements TestRule {
private SessionFactory sessionFactory;
private String configFilePath;
private ImmutableList<Class<?>> entities;
public static DropwizardHibernateRule create(ImmutableList<Class<?>> entities) {
return create("src/test/resources/test-db.yml", entities);
}
public static DropwizardHibernateRule create(String config, ImmutableList<Class<?>> entities) {
return new DropwizardHibernateRule(config, entities);
}
private DropwizardHibernateRule(String config, ImmutableList<Class<?>> entities) {
this.configFilePath = config;
this.entities = entities;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
@Override
public Statement apply(final Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
before();
try {
base.evaluate();
} finally {
after();
}
}
};
}
protected void before() throws IOException, ConfigurationException, ClassNotFoundException {
DatabaseConfiguration dbConfig = createDatabaseConfiguration();
final ManagedDataSource dataSource = new ManagedDataSourceFactory().build(dbConfig);
final ConnectionProvider provider = buildConnectionProvider(dataSource,
dbConfig.getProperties());
sessionFactory = buildSessionFactory(dbConfig, provider, ImmutableMap.<String, String> of(), entities);
// open session/transaction
ManagedSessionContext.bind(sessionFactory.openSession());
}
protected void after() {
// close session/transaction
ManagedSessionContext.unbind(sessionFactory);
}
/**
* Creates a DatabaseConfiguration from a File
*/
private DatabaseConfiguration createDatabaseConfiguration() throws IOException, ConfigurationException {
return ConfigurationFactory.forClass(DatabaseConfiguration.class, new Validator()).build(new File(configFilePath));
}
/**
* From com.yammer.dropwizard.hibernate.SessionFactoryFactory
*/
private ConnectionProvider buildConnectionProvider(DataSource dataSource,
ImmutableMap<String, String> properties) {
final DatasourceConnectionProviderImpl connectionProvider = new DatasourceConnectionProviderImpl();
connectionProvider.setDataSource(dataSource);
connectionProvider.configure(properties);
return connectionProvider;
}
/**
* From com.yammer.dropwizard.hibernate.SessionFactoryFactory
*/
private SessionFactory buildSessionFactory(DatabaseConfiguration dbConfig,
ConnectionProvider connectionProvider,
ImmutableMap<String, String> properties,
List<Class<?>> entities) {
final Configuration configuration = new Configuration();
configuration.setProperty(AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed");
configuration.setProperty(AvailableSettings.USE_SQL_COMMENTS, Boolean.toString(dbConfig.isAutoCommentsEnabled()));
configuration.setProperty(AvailableSettings.USE_GET_GENERATED_KEYS, "true");
configuration.setProperty(AvailableSettings.GENERATE_STATISTICS, "true");
configuration.setProperty(AvailableSettings.USE_REFLECTION_OPTIMIZER, "true");
configuration.setProperty(AvailableSettings.ORDER_UPDATES, "true");
configuration.setProperty(AvailableSettings.ORDER_INSERTS, "true");
configuration.setProperty(AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true");
configuration.setProperty("jadira.usertype.autoRegisterUserTypes", "true");
for (Map.Entry<String, String> property : properties.entrySet()) {
configuration.setProperty(property.getKey(), property.getValue());
}
addAnnotatedClasses(configuration, entities);
final ServiceRegistry registry = new ServiceRegistryBuilder()
.addService(ConnectionProvider.class, connectionProvider)
.applySettings(properties)
.buildServiceRegistry();
return configuration.buildSessionFactory(registry);
}
/**
* From com.yammer.dropwizard.hibernate.SessionFactoryFactory
*/
private void addAnnotatedClasses(Configuration configuration,
Iterable<Class<?>> entities) {
final SortedSet<String> entityClasses = Sets.newTreeSet();
for (Class<?> klass : entities) {
configuration.addAnnotatedClass(klass);
entityClasses.add(klass.getCanonicalName());
}
}
}
CREATE TABLE SOMEENTITY (
ID BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY NOT NULL,
VERSION BIGINT NOT NULL,
NAME VARCHAR(255)
);
insert into SOMEENTITY (version, name) values (0, 'moocows');
commit;
package org.yourcompany.domain;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
@Entity
@Table(name = "SOME_ENTITY")
@NamedQueries({
@NamedQuery(
name = "org.yourcompany.domain.SomeEntity.findAll",
query = "from SomeEntity"
)
})
public class SomeEntity {
@Id
private int id;
private String name;
@SuppressWarnings("unused")
private SomeEntity() {
}
public SomeEntity(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
package org.yourcompany.domain;
import static org.fest.assertions.api.Assertions.assertThat;
import java.util.List;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.yourcompany.service.YourService;
import org.yourcompany.test.DropwizardHibernateRule;
public class SomeEntityRepositoryIntegrationTest {
@Rule
public DropwizardHibernateRule dropwizardHibernateRule = DropwizardHibernateRule.create(YourService.hibernentities);
private SomeEntityRepository repository;
@Before
public void setUpSessionFactory() {
repository = new SomeEntityRepository(dropwizardHibernateRule.getSessionFactory());
}
@Test
public void herp() throws Exception {
List<SomeEntity> cpbs = repository.getAll();
assertThat(cpbs).isNotEmpty();
}
}
package org.yourcompany.domain;
import java.util.List;
import org.hibernate.SessionFactory;
import com.yammer.dropwizard.hibernate.AbstractDAO;
public class SomeEntityRepository extends AbstractDAO<SomeEntity> {
public SomeEntityRepository(SessionFactory sessionFactory) {
super(sessionFactory);
}
public List<SomeEntity> getAll() {
return list(namedQuery("org.yourcompany.domain.SomeEntity.findAll"));
}
}
# the name of your JDBC driver
driverClass: org.hsqldb.jdbc.JDBCDriver
# the username
user: sa
# the password
password:
# the JDBC URL
url: jdbc:hsqldb:hsql://localhost/somedb
# any properties specific to your JDBC driver:
properties:
charSet: UTF-8
# the maximum amount of time to wait on an empty pool before throwing an exception
maxWaitForConnection: 1s
# the SQL query to run when validating a connection's liveness
validationQuery: "SELECT 1"
# the minimum number of connections to keep open
minSize: 8
# the maximum number of connections to keep open
maxSize: 32
# whether or not idle connections should be validated
checkConnectionWhileIdle: false
# how long a connection must be held before it can be validated
checkConnectionHealthWhenIdleFor: 10s
# the maximum lifetime of an idle connection
closeConnectionIfIdleFor: 1 minute
package org.yourcompany.service;
import com.google.common.collect.ImmutableList;
import org.yourcompany.configuration.YourConfiguration;
import org.yourcompany.domain.SomeEntity;
import org.yourcompany.domain.SomeEntityRepository;
import com.yammer.dropwizard.Service;
import com.yammer.dropwizard.config.Bootstrap;
import com.yammer.dropwizard.config.Environment;
import com.yammer.dropwizard.db.DatabaseConfiguration;
import com.yammer.dropwizard.hibernate.HibernateBundle;
import com.yammer.dropwizard.hibernate.SessionFactoryFactory;
public class YourService extends Service<YourConfiguration> {
public static ImmutableList<Class<?>> hibernentities = ImmutableList.<Class<?>> of(SomeEntity.class);
private final HibernateBundle<YourConfiguration> hibernate = new HibernateBundle<YourConfiguration>(hibernentities, new SessionFactoryFactory()) {
@Override
public DatabaseConfiguration getDatabaseConfiguration(YourConfiguration configuration) {
return configuration.getDatabaseConfiguration();
}
};
@Override
public void initialize(Bootstrap<YourConfiguration> bootstrap) {
bootstrap.setName("derp");
bootstrap.addBundle(hibernate);
}
@Override
public void run(YourConfiguration configuration, Environment environment) throws Exception {
environment.addResource(new SomeResource(new SomeEntityRepository(hibernate.getSessionFactory())));
}
public static void main(String[] args) throws Exception {
new YourService().run(args);
}
}
@csterwa
Copy link

csterwa commented Jul 17, 2014

This is a great gist. Thanks.

Do you have an updated version for use with 0.7**+ of Dropwizard?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment