How to support transactions with JUnit and Demoiselle 2.4.2

1

I have an application whose unit tests are in full operation, except for write operations in the database. No data is recorded. When forcing a flush, I got the message stating that no transaction was in progress, even though the BusinessController method was annotated with @Transactional . Everything works correctly in the normal execution of the application inside JBoss, only in test cases the problem manifests itself. My persistence.xml is below:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="restaurante-ds" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>

        <class>...</class>

        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
            <property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver" />
            <property name="hibernate.connection.url" value="jdbc:oracle:thin:@servidororacle" />
            <property name="hibernate.connection.username" value="username" />
            <property name="hibernate.connection.password" value="password" />
            <property name="hibernate.default_schema" value="schema" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
        </properties>
    </persistence-unit>
</persistence>

What's missing?

Update 1

As per guideline, the /src/test/resources/META-INF/beans.xml file has been changed to contain the Demoiselle interceptor class, as below:

<?xml version="1.0"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
    <interceptors>
        <class>br.gov.frameworkdemoiselle.transaction.TransactionalInterceptor</class>
    </interceptors>
 </beans>

The behavior actually changed since before the call of the insert() method of my BusinessController ( restauranteUnidadeBC ) did not perform any operation in the BD, but now I get an exception with the following message:

Você está tentando obter um objeto não reconhecido pelo CDI via Beans.getReference(javax.transaction.UserTransaction)

Apparently there is still something missing. The test code follows below:

@Test
public void shouldAbrirCaixaComUsuarioLogado() {
    // Arrange
    Pessoa operador = pessoaBC.byChave("11111111111"); 
    RestauranteUnidade unidade = new RestauranteUnidade("Teste");
    unidade.getOperadores().add(operador);
    unidade = restauranteUnidadeBC.insert(unidade); // <<<< EXCEÇÃO AQUI!!!
    BigDecimal valorAbertura = new BigDecimal(10.50);

    // Act
    ...
}

The first invocation, which gets the operator works as expected.

Update 2

In order to give more subsidies, I provide the exceptions trace corresponding to the error:

br.gov.frameworkdemoiselle.DemoiselleException: Você está tentando obter um objeto não reconhecido pelo CDI via Beans.getReference(javax.transaction.UserTransaction)
    at br.gov.frameworkdemoiselle.util.Beans.getReference(Beans.java:132)
    at br.gov.frameworkdemoiselle.transaction.JTATransaction.getDelegate(JTATransaction.java:65)
    at br.gov.frameworkdemoiselle.transaction.JTATransaction.isActive(JTATransaction.java:77)
    at br.gov.frameworkdemoiselle.transaction.TransactionalInterceptor.initiate(TransactionalInterceptor.java:135)
    at ... diversas outras chamadas

By this trace we can see that the problem manifests itself in a method of class JTATransaction .

It was commented on the unavailability of some necessary dependence. Here is a simplified version of pom.xml for evaluation:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://maven.apache.org/POM/4.0.0"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    ... divresas definições 

    <packaging>war</packaging>
    <parent>
        <groupId>br.gov.frameworkdemoiselle</groupId>
        <artifactId>demoiselle-jsf-parent</artifactId>
        <version>2.4.2</version>
    </parent>

    <dependencies>
        ... diversas dependências próprias
        <!-- Dependências do SERPRO Demoiselle -->
        <dependency>
            <groupId>br.gov.frameworkdemoiselle</groupId>
            <artifactId>demoiselle-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>br.gov.frameworkdemoiselle</groupId>
            <artifactId>demoiselle-jta</artifactId>
        </dependency>
        <dependency>
            <groupId>br.gov.frameworkdemoiselle</groupId>
            <artifactId>demoiselle-servlet</artifactId>
        </dependency>

        ... outras dependências específicas do projeto incluindo Hibernate

        <!-- Dependências para suporte ao JUnit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version><!--$NO-MVN-MAN-VER$-->
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>simple-jndi</groupId>
            <artifactId>simple-jndi</artifactId>
            <version>0.11.4.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>br.gov.frameworkdemoiselle.component</groupId>
            <artifactId>demoiselle-junit</artifactId>
            <version>2.3.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>br.gov.frameworkdemoiselle.component</groupId>
            <artifactId>demoiselle-validation</artifactId>
            <version>2.0.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0.4</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    ... definições de plug-ins do Maven    
</project>

The suspicion about a missing dependency seems justified, because as a test I added to the test project a class implementing the interface UserTransaction and the CDI error stopped occurring. Since the class was dummy , I did not get any more error, but I came back to the situation where DB change operations have no effect.

Other evidence is the Eclipse console log:

08:12:50,144  INFO Version:207 - WELD-000900 1.1.8 (Final)
08:12:50,418  INFO Bootstrap:245 - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
08:12:50,699  INFO CoreBootstrap:209 - Ligando os motores do Demoiselle 2.4.2
08:12:50,702  INFO CoreBootstrap:209 - BeanManager disponível através do utilitário br.gov.frameworkdemoiselle.util.Beans
08:12:52,510  INFO CoreBootstrap:209 - O Demoiselle 2.4.2 decolou

I reiterate that the application works to the satisfaction, the problem only manifests itself in the context of JUnit.

Update 3

After removing the dependency of demoiselle-jta , no perceptible difference was observed, the problem persists. Below the console log from the beginning to the end of the operation:

08:42:01,197  INFO Version:207 - WELD-000900 1.1.8 (Final)
08:42:01,518  INFO Bootstrap:245 - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
08:42:01,813  INFO CoreBootstrap:209 - Ligando os motores do Demoiselle 2.4.2
08:42:01,818  INFO CoreBootstrap:209 - BeanManager disponível através do utilitário br.gov.frameworkdemoiselle.util.Beans
08:42:03,678  INFO CoreBootstrap:209 - O Demoiselle 2.4.2 decolou
08:42:06,402  INFO Version:24 - Hibernate Validator 4.2.0.Final
08:42:11,643  INFO Version:37 - HCANN000001: Hibernate Commons Annotations {4.0.1.Final}
08:42:11,697  INFO Version:41 - HHH000412: Hibernate Core {4.1.7.Final}
08:42:11,717  INFO Environment:239 - HHH000206: hibernate.properties not found
08:42:11,724  INFO Environment:342 - HHH000021: Bytecode provider name : javassist
08:42:13,585  INFO DriverManagerConnectionProviderImpl:96 - HHH000402: Using Hibernate built-in connection pool (not for production use!)
08:42:13,891  INFO DriverManagerConnectionProviderImpl:130 - HHH000115: Hibernate connection pool size: 20
08:42:13,892  INFO DriverManagerConnectionProviderImpl:133 - HHH000006: Autocommit mode: true
08:42:13,893  INFO DriverManagerConnectionProviderImpl:147 - HHH000401: using driver [oracle.jdbc.OracleDriver] at URL [jdbc:oracle:thin:@aikanahml.cce.ufpr.br:1521:hml01]
08:42:13,894  INFO DriverManagerConnectionProviderImpl:152 - HHH000046: Connection properties: {user=restaurante_test, password=****, autocommit=true, release_mode=auto}
08:42:15,132  INFO Dialect:125 - HHH000400: Using dialect: org.hibernate.dialect.Oracle10gDialect
08:42:15,297  INFO TransactionFactoryInitiator:73 - HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
08:42:15,332  INFO ASTQueryTranslatorFactory:48 - HHH000397: Using ASTQueryTranslatorFactory
08:42:35,107  INFO LoggerProducer:209 - Gerenciador de entidades criado a partir da unidade de persistência "restaurante-ds".
Hibernate: alguns selects necessários que antecedem o INSERT
...
>>> Aqui ocorreu a exceção, mas nenhuma mensagem é registrada no console, apenas em debug é possível rastrear a exceção e inspecionar seus detalhes

08:44:09,578  INFO CoreBootstrap:209 - Desligando os motores do Demoiselle 2.4.2
08:44:09,579  INFO DriverManagerConnectionProviderImpl:156 - HHH000030: Cleaning up connection pool [jdbc:oracle:thin:@aikanahml.cce.ufpr.br:1521:hml01]
    
asked by anonymous 01.02.2017 / 14:34

1 answer

2

Transaction annotations are processed by a JavaEE interceptor ( br.gov.frameworkdemoiselle.transaction.TransactionalInterceptor ).

Make sure it:

1) It is correctly declared in src/main/resources/META-INF/beans.xml of your application and does not exist the same file in src/test/resources/META-INF/ or

2) There is the file in both directories and it has the same content. Remember that during testing, the file that prevails is src/test/resources/META-INF/

Update 1

Apparently, the CDI is failing to find an implementation of the javax.transaction.UserTransaction class to inject. Generally, these classes are inside dependencies demoiselle-jpa or demoiselle-jta . Make sure one of these dependencies is declared in pom.xml of your project.

Another thing that may be hindering is the existence of a badly configured persistence.xml in the src/test/resources directory. Like beans.xml , if there is this file in this location, it prevails over src/main/resources while running unit tests.

Update 2

@AlexSC, from the Demoiselle documentation, I understand you should choose one of the two possible strategies: JPA or JTA. I noticed that you have both declared in your pom.xml .

I suggest testing with only one of them and removing the other dependency. Remembering according to the documentation , if you choose JTA, you need:

  • Set your persistence.xml attribute to transaction-type="JTA" in persistence-unit and
  • Include property hibernate.transaction.jta.platform pointing to correct class.

Update 3

Demoiselle has a Maven archetype, demoiselle-jsf-jpa , which features a unit test with access to BD. My suggestion is you create another project using the archetype as the base and check the configuration differences between it and your project.

The archetype catalog is available at link .

    
01.02.2017 / 14:56