How to support transactions with Junit and Demoiselle 2.4.2

Asked

Viewed 257 times

1

I have an application whose unit tests are fully operational except for write operations in the database. No data is recorded. When forcing a flush, I received the message indicating 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 within Jboss, only in the test cases the problem manifests itself. Mine persistence.xml goes 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 is missing?

Update 1

According to orientation, the file /src/test/resources/META-INF/beans.xml was 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 effectively changed, because before the call of the method insert() of my BusinessController (restauranteUnidadeBC) did not perform any operation in 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 still missing something. 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 give the list of exceptions 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 realize that the problem manifests itself in a class method JTATransaction.

It has been commented on the unavailability of some necessary dependency. Below 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 regarding a missing dependency seems justified, because by way of a test I added to the test project a class implementing the interface UserTransaction and the CDI error stopped occurring. As the class was dummy, I had no more mistake, but I returned to the situation where BD change operations have no effect.

Another 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 satisfactorily, the problem only manifests in the context of Junit.

Update 3

After the removal of the dependency on demoiselle-jta, no noticeable 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]
  • some progress after reply update 2?

  • @Joaquimoliveira, sorry, I did not realize that the reply had received update. I changed the pom to set the scope from the JTA dependency to compile and the JPA dependency was left with the scope configured to test, but this did not alter the behavior of the problem. I had not attacked myself from the dependency conflict because it does not affect the execution of the application, only of the tests. In short, I remain in the same.

  • @Joaquimoliveira, I removed JTA’s dependency on pom. The application runs smoothly, even if on persistence.xml i have the Unit persistence type setting for JTA. The problem has not changed. When I removed the JPA dependency and left only the JTA dependency, the application was no longer started.

  • @Joaquimoliveira, rectifying, after removing the dependency of Démoiselle-jpa I started to have an error a part of the application, in the case a DAO dependent on JPACrudExtended<>, during an update process. Therefore, I had to replace the dependency of Moiselle-jpa.

  • my suggestion was to withdraw the Demoiselle-jta, assuming your application does not require distributed transactions.

  • @Joaquimoliveira: removed dependency on demoiselle-jta, but the problem does not seem to have changed. In the code snippet where I do an Insert I get an exception with the message Você está tentando obter um objeto não reconhecido pelo CDI via Beans.getReference(javax.transaction.UserTransaction). Any more ideas? Have you ever performed unit tests with transactional operations in the BD? Demoiselle actually supports this scenario?

  • see if the new answer update helps. Hugs.

Show 2 more comments

1 answer

2


Transaction annotations are processed by a Javaee Interceptor (br.gov.frameworkdemoiselle.transaction.TransactionalInterceptor).

Make sure he:

1) It is stated correctly in src/main/resources/META-INF/beans.xml its implementation and that the same file does not exist in the src/test/resources/META-INF/ or

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

Update 1

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

Another thing that may be getting in the way is the existence of a persistence.xml misconfigured in directory src/test/resources. In the same way as the beans.xml, if there is this file at this location, it prevails over the src/main/resources during the execution of the unit tests.

Update 2

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

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

  • Set up in your persistence.xml the attribute transaction-type="JTA" in persistence-unit and
  • Include ownership hibernate.transaction.jta.platform pointing to the right class.

Update 3

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

The archetypes catalog is available at http://demoiselle.sourceforge.net/repository/archetype-catalog.xml.

  • Guidance seems to be on the right track, but I think there is still something missing. I added details to the question. Thank you!

  • @Alexsc, your unit test runs on Oracle?

  • yes it runs on Oracle

  • I added a few more details to the question. I would like to inform you that the beans.xml of each project is different. in the case of the tests, I have a reference to the transaction Javaee Interceptor provided by Demoiselle (br.gov.frameworkdemoiselle.transaction.TransactionalInterceptor), fact that does not occur in the beans.xml of the application

  • the tip of studying the Bookmark sample project was happy. In it I could notice differences existing in the files beans.xml and demoiselle.propertieswho turned out to be absolutely mandatory for everything to work. Thank you!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.