5 Replies Latest reply on Sep 28, 2016 9:10 AM by tsobis

    Different datasources for testing with wildfly 10 and hibernate 5.2

    tsobis

      Hello,

      I am using wildfly 10 with Hibernate core 5.2.0 which is included.

      The project has two datasources and the only way to make it work is to add the attribute catalog to the annotation of each of the entity beans

      eg.

      Database 1 → noline

      Database 2 → homeroom
      Entities from database 1 should include the catalog=noline on the annotion @Table

      @Table(name=”remote_instance”,catalog=”noline”)

      @Table(name=”redirect_instance”,catalog=”noline”)

       

      Entities from database 2 should include the catalog=homeroom on the annotion @Table

      @Table(name=”reporter”,catalog=”homeroom”)

      @Table(name=”current_location”,catalog=”homeroom”)


      The catalog is required by the hibernate and therefore I cannot remove it.

      When testing I want to use different datasources for obvious reasons. Since, I have done this before I thought it would be very easy.

      eg.

      Database 1 → noline_test

      Database 2 → homeroom_test

      So on the ShrinkWrapDeployment I added

      .addAsResource(“META-INF\test-persistence.xml”,”META-INF\persistence.xml”)

      to overwrite the persistence.xml with different datasources that point to different databases.


      When the test runs the data are persisted on the original databases and not on the test databases.

      So obviously this is a big problem, when running the tests the data should be from the test databases.

      After a lot of testing the only problem I can find is the catalog attribute.

      In this situation can I use arquillian with different datasources?


      Regards

      Tsobis George

        • 1. Re: Different datasources for testing with wildfly 10 and hibernate 5.2
          bmajsak

          Are you using pure Arquillian or together with Persistence Extension?

          • 2. Re: Different datasources for testing with wildfly 10 and hibernate 5.2
            tsobis

            Hello again,

            Yes i am using persistence extensions as well as drone, graphene and selenium-java

            • 3. Re: Different datasources for testing with wildfly 10 and hibernate 5.2
              bmajsak

              Can you share more details such as:

              persistence.xml, arquillian.xml and data sets?

               

              Thah would help me understand the problem better.

              • 4. Re: Different datasources for testing with wildfly 10 and hibernate 5.2
                tsobis

                The web app has two databases that can be accessed through the following datasources

                • java:/nolineGatewayDS
                • java:/homeroomDevDS

                 

                persistence.xml

                <?xml version="1.0" encoding="UTF-8" standalone="no"?>
                <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
                             version="2.1">
                    <persistence-unit name="gatewayPrimary" transaction-type="JTA">
                        <description>Gateway Primary Data Source</description>
                        <jta-data-source>java:/nolineGatewayDS</jta-data-source>
                        <class>com.tsobis.framework.model.entity.SiteConfiguration</class>
                        <class>com.tsobis.app.model.entity.app.remote.instance.RemoteInstance</class>
                        <properties>
                            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
                            <property name="hibernate.transaction.flush_before_completion" value="true"/>
                            <property name="hibernate.show_sql" value="true"/>
                            <property name="hibernate.format_sql" value="true"/>
                            <property name="hibernate.cache.use_second_level_cache" value="true" />
                            <property name="hibernate.cache.use_minimal_puts" value="true"/>
                            <property name="hibernate.cache.infinispan.statistics" value="false"/>
                            <property name="hibernate.cache.region_prefix" value="nolineGatewayDS"/>
                        </properties>
                    </persistence-unit>
                    <persistence-unit name="homeroomDev" transaction-type="JTA">
                        <description>Home room Data source</description>
                        <jta-data-source>java:/homeroomDevDS</jta-data-source>
                        <class>com.tsobis.app.model.entity.commerce.b2b.Customer</class>
                       <exclude-unlisted-classes>true</exclude-unlisted-classes>
                        <properties>
                            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
                            <property name="hibernate.transaction.flush_before_completion" value="true"/>
                            <property name="hibernate.show_sql" value="true"/>
                            <property name="hibernate.format_sql" value="true"/>
                            <property name="hibernate.cache.use_second_level_cache" value="true" />
                            <property name="hibernate.cache.use_minimal_puts" value="true"/>
                            <property name="hibernate.cache.infinispan.statistics" value="false"/>
                            <property name="hibernate.cache.region_prefix" value="homeroomDevDS"/>
                        </properties>
                    </persistence-unit>
                </persistence>
                
                

                 

                 

                Than with cdi i produce the two entitymanagers with the different @PersistenceContext

                public class PersistenceResources
                {
                    @Produces
                    @PersistenceContext(unitName = "gatewayPrimary")
                    private EntityManager emGateway;
                
                    @Produces
                    @PersistenceContext(unitName = "homeroomDev")
                    private EntityManager emhomeroomDev;
                }
                
                
                

                 

                 

                 

                 

                The entity beans look like this

                
                @Entity
                @Table(name = "remote_instance",catalog="noline")
                @NamedQueries({
                        @NamedQuery(name="RemoteInstance.countAll",query="SELECT COUNT(DISTINCT remoteInstanceDB.instanceId) FROM RemoteInstance remoteInstanceDB "),
                
                })
                public class RemoteInstance implements java.io.Serializable
                {
                    private Long instanceId;
                    private String cdesc;
                    private String hostname;
                    private String sshPort;
                    public RemoteInstance(){.....}
                and the getter setter methods
                }
                
                

                 

                 

                
                @Entity
                @Table(name = "customer",uniqueConstraints = @UniqueConstraint(columnNames = "email"),catalog="homeroom")
                @NamedQueries({
                        @NamedQuery(name="Customer.findByPK",query="SELECT emploDB FROM Customer emploDB WHERE emploDB.customerId=:id")
                })
                public class Customer implements java.io.Serializable
                {
                
                    private Long customerId;
                    private String cusername;   
                    private String email;
                
                
                    public Customer(){.....}
                
                getter setter methods
                }
                
                
                
                
                
                

                 

                 

                 

                 

                For the tests I want to use a different persistence.xml that will point to two different datasources and therefore different databases.

                So for testing I am using test-persistence.xml

                Here the datasources are:

                • java:/nolineGatewayTestDS
                • java:/homeroomDevTestDS

                 

                <?xml version="1.0" encoding="UTF-8" standalone="no"?>
                <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
                             version="2.1">
                    <persistence-unit name="gatewayPrimary" transaction-type="JTA">
                        <description>Gateway Primary Data Source for tests</description>
                        <jta-data-source>java:/nolineGatewayTestDS</jta-data-source>
                        <class>com.tsobis.framework.model.entity.SiteConfiguration</class>
                <class>com.tsobis.app.model.entity.app.remote.instance.RemoteInstance</class>
                
                        <exclude-unlisted-classes>true</exclude-unlisted-classes>
                        <properties>
                            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
                            <property name="hibernate.transaction.flush_before_completion" value="true"/>
                
                            <property name="hibernate.show_sql" value="true"/>
                            <property name="hibernate.format_sql" value="true"/>
                
                            <property name="hibernate.cache.use_second_level_cache" value="true" />
                            <property name="hibernate.cache.use_minimal_puts" value="true"/>
                            <property name="hibernate.cache.infinispan.statistics" value="false"/>
                            <property name="hibernate.cache.region_prefix" value="nolineGatewayTestDS"/>
                        </properties>
                    </persistence-unit>
                    <persistence-unit name="homeroomDev" transaction-type="JTA">
                        <description>GHome room Data source for tests</description>
                        <jta-data-source>java:/homeroomDevTestDS</jta-data-source>
                        <class>com.tsobis.app.model.entity.commerce.b2b.Customer</class>
                <exclude-unlisted-classes>true</exclude-unlisted-classes>
                        <properties>
                            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
                            <property name="hibernate.transaction.flush_before_completion" value="true"/>
                           
                            <property name="hibernate.show_sql" value="true"/>
                            <property name="hibernate.format_sql" value="true"/>          
                            <property name="hibernate.cache.use_second_level_cache" value="true" />
                            <property name="hibernate.cache.use_minimal_puts" value="true"/>
                            <property name="hibernate.cache.infinispan.statistics" value="false"/>
                            <property name="hibernate.cache.region_prefix" value="homeroomDevTestDS"/>
                        </properties>
                
                
                
                
                
                    </persistence-unit>
                </persistence>
                
                

                 

                The arquillian.xml has a very simple setup

                 

                <arquillian xmlns="http://jboss.org/schema/arquillian"
                            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                            xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
                    <container qualifier="arq-wildfly10-managed" default="true">
                        <configuration>
                            <property name="serverConfig">standalone-full.xml</property>
                            <property name="outputToConsole">true</property>
                            <property name="managementAddress">127.0.0.1</property>
                            <property name="managementPort">9990</property>
                            <property name="username">.......</property>
                            <property name="password">......</property>
                            <property name="javaVmArguments">-Xms64m -Xmx2G</property>
                        </configuration>
                    </container>
                
                    <extension qualifier="webdriver">
                        <property name="browser">firefox</property>
                        <property name="loggingPrefs">driver=INFO,profiler=WARNING</property>
                    </extension>
                
                </arquillian>
                
                
                
                

                 

                 

                 

                Finally for the test

                
                public class ShrinkWrapDeployment
                {
                    private static final String WEBAPP_SRC = "src/main/webapp/";
                    private static final String TEST_WEBAPP_SRC = "src/test/webapp/";
                
                    private WebArchive webArchive;
                    public ShrinkWrapDeployment() {webArchive = ShrinkWrap.create(WebArchive.class, "test.war") .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");}
                    public WebArchive getArchive() {return webArchive;}
                
                
                    public ShrinkWrapDeployment withClasses()
                    {
                        webArchive = webArchive
                                .addPackages(true, Filters.exclude(SchedulerFramework.class,AuthFilter.class), "com.tsobis.framework")
                                .addPackages(true, "com.tsobis.app");
                        return this;
                    }
                
                    public ShrinkWrapDeployment withMaven()
                    {
                        File[] libs = Maven.resolver().loadPomFromFile("pom.xml").importRuntimeAndTestDependencies().resolve().withTransitivity().asFile();
                        webArchive = webArchive.addAsLibraries(libs).addAsResource("web.xml", "WEB-INF/web.xml");
                        return this;
                    }
                
                    public ShrinkWrapDeployment withCustomPersistenceUnit()
                    {
                        webArchive = webArchive.addAsResource("META-INF/test-persistence.xml", "META-INF/persistence.xml");
                        return this;
                    }
                    public ShrinkWrapDeployment addFacesNComponents(boolean addFacesComponents)
                    {
                        if(!addFacesComponents){webArchive = webArchive.addAsWebInfResource(EmptyAsset.INSTANCE, "faces-config.xml");;}
                        else
                        {
                            webArchive = webArchive.addAsWebInfResource(new File(WEBAPP_SRC+"WEB-INF/faces-config.xml"))
                                    .addAsResource("com/messages_en.properties")
                                    .addAsResource("com/messages_el.properties");
                        }
                        return this;
                    }
                
                }
                
                
                
                
                
                
                
                
                

                 

                 

                All the above files are examples since they are redacted.

                 

                And on the actual test file

                 

                @RunWith(Arquillian.class)
                public class RemoteInstanceActionsTest
                {
                    @Deployment
                    public static WebArchive createDeployment()
                    {
                        return new ShrinkWrapDeployment().withClasses().withMaven().withCustomPersistenceUnit().addFacesNComponents(true).getArchive();
                    }
                
                    @EJB
                    RemoteInstanceActions remoteInstanceActions;
                
                    @Test
                    public void createRemoteInstance()
                    {
                        RemoteInstance selectedRemoteInstance = new RemoteInstance();
                        
                        selectedRemoteInstance.setCdesc("test");
                        selectedRemoteInstance.setHostname("www.test.com");
                        selectedRemoteInstance.setSshPort("8990");
                      
                      
                      
                        ActionResponse actionCreateResponse = remoteInstanceActions.createRemoteInstance(selectedRemoteInstance);
                        selectedRemoteInstance= (RemoteInstance)actionCreateResponse.getParameter("remoteInstance");
                
                        Assert.assertTrue(actionCreateResponse.getReplyIsCorrect());
                        Assert.assertNotEquals(0L, selectedRemoteInstance.getInstanceId().longValue());
                    }
                }
                
                
                
                
                
                
                

                 

                This is for example a small stupid test. The method createRemoteInstance() from the RemoteInstanceActions persists the data to the database table.

                The test passes, however, the data are persisted on the wrong database,

                since for the tests i am using the test-persistence.xml the datasource that is used is the

                java:/nolineGatewayTestDS and therefore the database is noline_test, and the table is remote_instance, however, the data are persisted on the

                database is noline.remote_instance which the other datasource.


                If i change the attribute catalog (that exists on the entity beans) from catalog="noline" to catalog="noline_test"

                the result is as expected. With previous versions of hibernate the catalog attribute was optional, however with the version 5.2 wildfly will not even start without it.

                I have used the same setup on previous projects however with older versions of hibernate and single datasource.


                • 5. Re: Different datasources for testing with wildfly 10 and hibernate 5.2
                  tsobis

                  After a lot of testing with most of the hibernate versions I could not solve my problem with the older version of wildfly 10. The problem was solved with the new version of wildfly 10.1.0.Final.

                  Hibernate does not require the catalog attribute on the entity beans and thus solved my problem.

                  Keep in mind that the new wildfly requires the connection-property tag on the datasource eg.

                  <connection-property name="databaseName">your_dbname</connection-property>