0 Replies Latest reply on Oct 18, 2016 4:32 AM by Marcin M

    Wildfly 10, Spring and Hibernate - transaction configuration problem

    Marcin M Newbie

      I cannot figure out how to properly configure transaction manager to be used with Wildfly and Hibernate. My configuration is:

      <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">      
      <property name="dataSource" ref="dataSource"/>
      <property name="hibernateProperties">
           <!-- All properties provided by application server environment -->
           <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>     
                <prop key="hibernate.hbm2ddl.auto">validate</prop> <!-- Second level cache configuration -->     
                <prop key="hibernate.cache.use_second_level_cache">false</prop>     
                <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>     
                <prop key="hibernate.generate_statistics">true</prop>     
                <prop key="hibernate.cache.use_structured_entries">true </prop>  
                <!-- Query cache -->   
                <prop key="hibernate.cache.use_query_cache">false</prop>
                <prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop>     
                <prop key="hibernate.cache.provider_configuration_file_resource_path"> "" </prop>     
                <prop key="jadira.usertype.autoRegisterUserTypes">true</prop>
                <prop key="jadira.usertype.databaseZone">jvm</prop>     
                <prop key="jadira.usertype.javaZone">jvm</prop>
                <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
                <prop key="hibernate.transaction.manager_lookup_class"> org.hibernate.transaction.JBossTransactionManagerLookup </prop>
                <prop key="hibernate.transaction.jta.platform">jta</prop>
           </props>
      </property>
      <property name="packagesToScan" value="org.example"/>
      </bean>

      <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
           <property name="allowCustomIsolationLevels" value="true"/>
      </bean>

      what I would like to achieve is having a transactional service bean containing two other beans with database access, using the same transaction.

      @Service("terminalQueryService") public class UserQueryServiceImpl implements UserQueryService {  
       
        @Transactional
      (readOnly = true, propagation = Propagation.REQUIRED)
        public PaginatedList<PetDto> browse(PageDefinition pageDefinition, String userLogin) {
           User user = null;
           try {
                user
      = userQueriesFacade.getUser(userLogin);     
           } catch (AuthorizationServiceException e) { return PaginatedList.getEmptyList(); }
           PaginatedList<Pet> petListagedList = petQueriesFacade.browse( pageDefinition, user.getId()); 
           List<PetDto> petDtoList = new ArrayList<>();
           List<Pet> petEntityList = petEntityPagedList.getList();
           dtoMapper
      .assembleDtos("petDtoKey", petDtoList, petEntityList);
           return petEntityPagedList.transform(petDtoList);
        }
      }

      the query fasades look like:

      @Cacheable("userForSecurity") 
      @Transactional(propagation = Propagation.REQUIRED)
      public User getUser(PageDefinition pageDefinition, String login) { 
           User user = (User) getSession() .createQuery( "from User mu left outer join
                               fetch mu.additionalPrivileges left outer join fetch mu.roles
                               where mu.login = :login AND mu.status != :archivedStatus"
      )
                               .setParameter("login", login)
                               .setParameter("archivedStatus", UserStatus.ARCHIVED) .uniqueResult();
           return user;
      }

      the error I get is

      WARN  [org.springframework.remoting.support.RemoteInvocationTraceInterceptor] (default task-38) Processing of HttpInvokerServiceExporter remote call 
      resulted in fatal exception
      : org.example.logic.remote.services.user.UserQueryService.browse:
      org
      .hibernate.LazyInitializationException: could not initialize proxy - no Session

      on the line that it trying to transforms dto what suggest me that session was closed.

      if I remove @Transactional from fasades then (and leave it on the service) the first query executes without any problem, the second raises:

      [org.springframework.remoting.support.RemoteInvocationTraceInterceptor] (default task-37) Processing of HttpInvokerServiceExporter remote call 
      resulted in fatal exception
      : org.example.logic.remote.services.user.UserQueryService.browse:
      org
      .hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
      at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
      at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:988)

      any ideas?