All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.dropwizard.testing.common.DAOTest Maven / Gradle / Ivy

There is a newer version: 5.0.0-alpha.2
Show newest version
package io.dropwizard.testing.common;

import io.dropwizard.logging.common.BootstrapLogging;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.context.internal.ManagedSessionContext;

import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.function.Consumer;

public class DAOTest {
    @SuppressWarnings("unchecked")
    public abstract static class Builder> {
        private String url = "jdbc:h2:mem:" + UUID.randomUUID();
        private String username = "sa";
        private String password = "";
        private String driver = "org.h2.Driver";
        private String hbm2ddlAuto = "create";
        private boolean showSql = false;
        private boolean useSqlComments = false;
        private boolean bootstrapLogging = true;
        private final Set> entityClasses = new LinkedHashSet<>();
        private final Map properties = new HashMap<>();
        private Consumer configurationCustomizer = c -> {
        };

        public B setUrl(String url) {
            this.url = url;
            return (B) this;
        }

        public B setUsername(String username) {
            this.username = username;
            return (B) this;
        }

        public B setPassword(String password) {
            this.password = password;
            return (B) this;
        }

        public B setDriver(Class driver) {
            this.driver = driver.getName();
            return (B) this;
        }

        public B setDriver(String driver) {
            this.driver = driver;
            return (B) this;
        }

        public B setHbm2DdlAuto(String hbm2ddlAuto) {
            this.hbm2ddlAuto = hbm2ddlAuto;
            return (B) this;
        }

        public B setShowSql(boolean showSql) {
            this.showSql = showSql;
            return (B) this;
        }

        public B useSqlComments(boolean useSqlComments) {
            this.useSqlComments = useSqlComments;
            return (B) this;
        }

        /**
         * @since 2.0
         */
        public B bootstrapLogging(boolean value){
            bootstrapLogging = value;
            return (B) this;
        }

        public B addEntityClass(Class entityClass) {
            this.entityClasses.add(entityClass);
            return (B) this;
        }

        public B setProperty(String key, String value) {
            this.properties.put(key, value);
            return (B) this;
        }

        public B customizeConfiguration(Consumer configurationCustomizer) {
            this.configurationCustomizer = configurationCustomizer;
            return (B) this;
        }

        protected DAOTest buildDAOTest() {
            if (bootstrapLogging) {
                BootstrapLogging.bootstrap();
            }

            final Configuration config = new Configuration();
            config.setProperty(AvailableSettings.URL, url);
            config.setProperty(AvailableSettings.USER, username);
            config.setProperty(AvailableSettings.PASS, password);
            config.setProperty(AvailableSettings.DRIVER, driver);
            config.setProperty(AvailableSettings.HBM2DDL_AUTO, hbm2ddlAuto);
            config.setProperty(AvailableSettings.SHOW_SQL, String.valueOf(showSql));
            config.setProperty(AvailableSettings.USE_SQL_COMMENTS, String.valueOf(useSqlComments));
            // Use the same configuration as in the Hibernate bundle to reduce differences between
            // testing and production environments.
            config.setProperty(AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed");
            config.setProperty(AvailableSettings.USE_GET_GENERATED_KEYS, "true");
            config.setProperty(AvailableSettings.GENERATE_STATISTICS, "true");
            config.setProperty(AvailableSettings.USE_REFLECTION_OPTIMIZER, "true");
            config.setProperty(AvailableSettings.ORDER_UPDATES, "true");
            config.setProperty(AvailableSettings.ORDER_INSERTS, "true");
            config.setProperty(AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true");

            entityClasses.forEach(config::addAnnotatedClass);
            properties.forEach(config::setProperty);

            configurationCustomizer.accept(config);

            return new DAOTest(config.buildSessionFactory());
        }
    }

    private final SessionFactory sessionFactory;

    /**
     * Use {@link io.dropwizard.testing.junit5.DAOTestExtension#newBuilder()}
     */
    private DAOTest(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public void before() throws Throwable {
        if (ManagedSessionContext.hasBind(sessionFactory)) {
            return;
        }

        final Session session = sessionFactory.openSession();
        ManagedSessionContext.bind(session);
    }

    public void after() {
        if (!ManagedSessionContext.hasBind(sessionFactory)) {
            return;
        }

        final Session currentSession = sessionFactory.getCurrentSession();
        if (currentSession.isOpen()) {
            currentSession.close();
        }
        ManagedSessionContext.unbind(sessionFactory);
    }

    /**
     * Returns the current active session factory for injecting to DAOs.
     *`
     * @return {@link SessionFactory} with an open session.
     */
    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    /**
     * Performs a call in a transaction
     *
     * @param call the call
     * @param   the type of the returned result
     * @return the result of the call
     */
    public  T inTransaction(Callable call) {
        final Session session = sessionFactory.getCurrentSession();
        final Transaction transaction = session.beginTransaction();
        try {
            final T result = call.call();
            transaction.commit();
            return result;
        } catch (final Exception e) {
            transaction.rollback();
            if (e instanceof RuntimeException) {
              throw (RuntimeException) e;
            }
            throw new RuntimeException(e);
        }
    }

    /**
     * Performs an action in a transaction
     *
     * @param action the action
     */
    public void inTransaction(Runnable action) {
        inTransaction(() -> {
            action.run();
            return true;
        });
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy