Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/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
Java @两个不同LocalContainerEntityManagerFactoryBean上的PersistenceContext引发TransactionRequiredException_Java_Spring Boot_Jpa_Entitymanager - Fatal编程技术网

Java @两个不同LocalContainerEntityManagerFactoryBean上的PersistenceContext引发TransactionRequiredException

Java @两个不同LocalContainerEntityManagerFactoryBean上的PersistenceContext引发TransactionRequiredException,java,spring-boot,jpa,entitymanager,Java,Spring Boot,Jpa,Entitymanager,我设置了两个LocalContainerEntityManagerFactoryBeans,一个带有@Primary注释,另一个没有注释。这是因为我必须与两个不同的数据库通信,如果我删除@Primary装饰,我会得到一个重复的bean错误。两者的构造方式完全相同,这里有一个供参考: package com.myorg.rest.config.dba; import ... @Configuration @EnableJpaRepositories( basePackages = &q

我设置了两个
LocalContainerEntityManagerFactoryBean
s,一个带有
@Primary
注释,另一个没有注释。这是因为我必须与两个不同的数据库通信,如果我删除
@Primary
装饰,我会得到一个重复的bean错误。两者的构造方式完全相同,这里有一个供参考:

package com.myorg.rest.config.dba;

import ...

@Configuration
@EnableJpaRepositories(
    basePackages = "com.myorg.rest.dao.dbA",
    entityManagerFactoryRef = "dbAEntityManager",
    transactionManagerRef = "dbATransactionManager"
    )
@EnableTransactionManagement
public class DbADataSourceConfig {

    @Autowired
    private EnvProperties settings;

    @Bean
    @Primary
    public DataSource prjDataSource() {
        DataSourceProperties ds = settings.getdbADatasource();
        return ds.initializeDataSourceBuilder().type(BasicDataSource.class).build();
    }

    @Bean(name = "dbAEntityManager")
    @Primary
    public LocalContainerEntityManagerFactoryBean dbAEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(prjDataSource());
        em.setPackagesToScan(new String[] { "com.myorg.model.entities.dba" });
        em.setPersistenceUnitName("dbAUnit");

        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());
        // em.afterPropertiesSet();

        return em;
    }

    @Bean(name = "dbATransactionManager")
    @Primary
    public PlatformTransactionManager dbATransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(dbAEntityManager().getObject());

        return transactionManager;
    }

    Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        return properties;
    }
}
它们都是在DAO内部注入
@PersistenceContext(unitName=“dbunit”)
@PersistenceContext(unitName=“dbBUnit”)
,并且它们都成功地在DAO内部引导相应的EntityManager。我可以在两者中创建,然后检索创建的实体。但当我使用以下内容检索所有实体时:

public List<T> findAll() {
    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery<T> entityQuery = criteriaBuilder.createQuery(clazz);
    entityQuery.from(clazz);
    return entityManager.createQuery(entityQuery).getResultList();
}
然后,我尝试用
@Transactional
装饰DAO,并用
@Transactional
进一步装饰每个方法。还尝试了使用
@PersistenceContext(unitName=“dbunit”,type=PersistenceContextType.TRANSACTION)注入
,但所有这些尝试都会导致完全相同的错误


为什么“次要的”
@PersistenceContext
没有将事务放入?

当将多个事务管理器与
@Transactional
一起使用时,您需要声明要显式使用的事务管理器,否则总是选择
@Primary
管理器,您的第二
实体管理器
不可能加入其事务


尝试使用
@Transactional(“dbBTransactionManager”)
插入第二个持久性上下文,看看问题是否消失。

这正是我需要的,谢谢。但我不明白的是,如果我通过
@PersistenceContext(unitName='nnn')注入,为什么不会自动发生这种情况
如果您同时注入这两种情况呢?另外,Spring不理解持久性上下文和事务管理器之间的关系。如果我将两者都注入,我希望有两个事务,不是吗?当然,Spring是在JPA之上运行的,但是,它已经知道如何处理它了,因为在单个数据源和/或
@Primary
的情况下,它已经完美地工作了!也许是因为我不懂这里的基本知识,你有什么好的课程建议来解释这些吗?没有,对不起。老实说,我只是通过研究您的问题学会了如何处理多个
TransactionManager
s,并最终在Spring文档中找到了答案,我认为如果您使用调试器停止代码,并调用
TransactionSynchronizationManager.isActualTransactionActive()
在抛出
TransactionRequiredException
之前,它将返回
true
。问题是,这是您的代码无法使用的事务。而
TransactionRequiredException
来自Hibernate,而不是Spring
 Caused by:
            javax.persistence.TransactionRequiredException: no transaction is in progress
                at org.hibernate.internal.AbstractSharedSessionContract.checkTransactionNeededForUpdateOperation(AbstractSharedSessionContract.java:413)
                at org.hibernate.internal.SessionImpl.checkTransactionNeededForUpdateOperation(SessionImpl.java:3398)
                at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1355)
                at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1350)
                at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
                at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.base/java.lang.reflect.Method.invoke(Method.java:566)
                at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:366)
                at com.sun.proxy.$Proxy95.flush(Unknown Source)