Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在多数据源场景中配置Spring事务管理器的正确方法(hibernate 5.2.6)_Hibernate_Jpa_Spring Data Jpa_Wildfly_Transactionmanager - Fatal编程技术网

在多数据源场景中配置Spring事务管理器的正确方法(hibernate 5.2.6)

在多数据源场景中配置Spring事务管理器的正确方法(hibernate 5.2.6),hibernate,jpa,spring-data-jpa,wildfly,transactionmanager,Hibernate,Jpa,Spring Data Jpa,Wildfly,Transactionmanager,在将我的应用程序升级到Hibernate5.2.6(WAS5.0)和SpringCore升级到4.3.6之后,我开始出现大量臭名昭著的“无法为当前线程获得事务同步会话”hibernate异常 15:13:36,907 ERROR [foo.my.CustomLdapAuthoritiesPopulator] (default task-10) Error populating authorities: javax.persistence.TransactionRequiredException:

在将我的应用程序升级到Hibernate5.2.6(WAS5.0)和SpringCore升级到4.3.6之后,我开始出现大量臭名昭著的“无法为当前线程获得事务同步会话”hibernate异常

15:13:36,907 ERROR [foo.my.CustomLdapAuthoritiesPopulator] (default task-10) Error populating authorities: javax.persistence.TransactionRequiredException: no transaction is in progress
    at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3450)
    at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1418)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1414)
    at org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:144)
    at org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95)
此应用程序使用3个数据源,在Jboss Wildfly中都配置为非XA数据源,它们是:

  • Db1:mysql,使用Hibernate和旧的不推荐使用的标准API
  • Db2:mysql,普通JDBC
  • Db3:sql server,使用JPA CriteriaBuilder休眠
  • 没有跨数据库查询。每个服务都是@Transactional的,特定的服务、DAO和模型类(对于hibernate)在不同的包中分开。它们之间不存在引用

    问题是,我对如何以“正确的方式”配置事务管理器非常陌生。我唯一能找到的解决方案是精心修改每个@transaction注释,使其包含transaction manager名称:

    @Transactional(transactionManager="tmDb1")
    
    从而生成以下完整的application-context.xml文件(hibernate属性,省略xmlns名称空间)

    
    foo.my.framework.domain
    foo.my.app.model
    foo.my.app.model.db3model
    
    我的问题是:

  • 应使用多少个tx管理器?可以使用
    用一个来完成吗?我试过一些组合,但没用。如果可能,我只希望有一个事务管理器

  • 有没有办法(使用一个或多个tx管理器)避免在
    @Transactional
    注释中声明tx名称

  • 为什么在将hibernate从5.0迁移到5.2时会出现此错误?它与3tx:annotation驱动块完美配合,无需在
    @Transactional
    注释上指明TM的名称

  • 本质上,在spring中使用不同的数据源类型(有些使用实体管理器)配置多个数据源最干净的方法是什么

  • 一些评论:

    • 每个数据源在Wildfly中都配置为非XA
    • 我不介意使用容器事务管理器
    • 所有@Service类一次只处理一个数据库。无需将事务扩展到多个数据源
    更新1 经过一些调查,我认为spring没有在@Transactional属性中声明事务管理器名称,因此试图找到一个名为“transactionManager”的TM,所以(可能)这一直有效,因为所有DAO实际上都使用相同的默认TM?但仍然没有解释为什么它停止工作,然后升级Hibernate

    <?xml version="1.0" encoding="UTF-8"?>
    <beans>
    
        <task:annotation-driven />
        <mvc:annotation-driven></mvc:annotation-driven>
    
        <!-- Exclude controllers -->
        <context:component-scan base-package="foo.my.framework, foo.my.app">
            <context:exclude-filter type="regex" expression="foo\.my\.app\.web\.controllers\..*" />
        </context:component-scan>
    
        <!-- DB1 Datasource Hibernate mysql -->
        <bean id="DB1" class="org.springframework.jndi.JndiObjectFactoryBean">
            <property name="jndiName" value="java:/myconnections/db1-datasource" />
        </bean>
    
        <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
            <property name="dataSource" ref="DB1" />
            <property name="packagesToScan">
                <list>
                    <value>foo.my.framework.domain</value>
                    <value>foo.my.app.model</value>
                </list>
            </property>
        </bean>
    
        <bean id="tmDb1" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>
    
        <!-- DB2 Datasource JDBC mysql -->
        <bean id="DB2" class="org.springframework.jndi.JndiObjectFactoryBean">
            <property name="jndiName" value="java:/myconnections/db2-datasource" />
        </bean>
        <bean id="tmDb2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="DB2" />
        </bean>
    
        <!-- DB3 Datasource Hibernate SQL Server JPA CriteriaBuilder -->
        <bean id="DB3" class="org.springframework.jndi.JndiObjectFactoryBean">
            <property name="jndiName" value="java:/myconnections/db3-datasource" />
        </bean>
    
        <bean id="punDB3" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="persistenceUnitName" value="punDB3" />
            <property name="dataSource" ref="DB3" />
            <property name="packagesToScan">
                <list>
                    <value>foo.my.app.model.db3model</value>
                </list>
            </property>
            <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
            </property>
        </bean>
    
    
        <bean id="tmDb3" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="punDB3" />
        </bean>
    
        <tx:annotation-driven transaction-manager="tmDb1" />
        <tx:annotation-driven transaction-manager="tmDb2" />
        <tx:annotation-driven transaction-manager="tmDb3" />
    </beans>