Hibernate 在事务提交后不保存实体
Hibernate does not save entity after transaction commit
我有事务服务,我用它来创建一个人并将其保存在数据库中。
问题是提交事务后实体没有保存到数据库中。
起初我以为是 JpaRepository 的错,每次调用方法时它都会打开一个新事务,但据我了解,这些只是打开的单个物理事务中的逻辑事务为我服务。
我使用 Spring Boot 和 Hibernate 连接我的 firebird 数据库。
为此,我配置了两个独立的数据源和事务管理器。
在每个@Transactional 注释中,我指定要使用的事务管理器。
获取数据完美无缺。问题只涉及保存。
我实际上在这里执行了更多操作,但为了示例,我将限制自己只保存实体。
下面的简单示例。
@Transactional("secondaryTransactionManager")
@RequiredArgsConstructor
public class PersonServiceImpl implements PersonService {
private final PersonJpaRepository personJpaRepository;
@Override
public String savePerson() {
var personEntity = new PersonEntity();
personEntity.setName("Slawek");
personEntity.setSurname("Filip");
personEntity.setPersonalNumber("12341234123");
var save = personJpaRepository.save(personEntity);
return save.getName();
}
}
虽然个人实体没有保存在数据库中。有日志
2021-10-16 17:41:13.345 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : Getting transaction for [com.backend.declarations.service.impl.PersonServiceImpl.savePerson]
2021-10-16 17:41:13.772 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.toString]: This method is not transactional.
2021-10-16 17:41:13.967 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.toString]: This method is not transactional.
2021-10-16 17:41:14.716 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2021-10-16 17:41:14.728 DEBUG 884 --- [nio-8080-exec-3] o.s.orm.jpa.EntityManagerFactoryUtils : Opening JPA EntityManager
2021-10-16 17:41:14.728 TRACE 884 --- [nio-8080-exec-3] .i.SessionFactoryImpl$SessionBuilderImpl : Opening Hibernate Session. tenant=null
2021-10-16 17:41:14.729 TRACE 884 --- [nio-8080-exec-3] org.hibernate.internal.SessionImpl : Opened Session [16b4f365-b4f9-4267-bed6-a5057aad25a9] at timestamp: 1634398874728
2021-10-16 17:41:14.735 TRACE 884 --- [nio-8080-exec-3] o.hibernate.event.internal.EntityState : Transient instance of: com.backend.declarations.repository.entity.PersonEntity
2021-10-16 17:41:14.736 TRACE 884 --- [nio-8080-exec-3] o.h.e.i.DefaultPersistEventListener : Saving transient instance
2021-10-16 17:41:14.738 DEBUG 884 --- [nio-8080-exec-3] org.hibernate.SQL : select gen_id( GEN_OSOBY_ID, 1 ) from RDB$DATABASE
2021-10-16 17:41:14.750 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Registering statement [org.firebirdsql.jdbc.FBPreparedStatement@1b6]
2021-10-16 17:41:14.752 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Registering result set [org.firebirdsql.jdbc.FBResultSet@7e70efdc]
2021-10-16 17:41:14.760 DEBUG 884 --- [nio-8080-exec-3] o.h.id.enhanced.SequenceStructure : Sequence value obtained: 3422
2021-10-16 17:41:14.760 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing result set [org.firebirdsql.jdbc.FBResultSet@7e70efdc]
2021-10-16 17:41:14.760 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Closing result set [org.firebirdsql.jdbc.FBResultSet@7e70efdc]
2021-10-16 17:41:14.764 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing statement [org.firebirdsql.jdbc.FBPreparedStatement@1b6]
2021-10-16 17:41:14.764 DEBUG 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : HHH000387: ResultSet's statement was not registered
2021-10-16 17:41:14.764 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Closing prepared statement [org.firebirdsql.jdbc.FBPreparedStatement@1b6]
2021-10-16 17:41:14.764 TRACE 884 --- [nio-8080-exec-3] o.h.e.jdbc.internal.JdbcCoordinatorImpl : Starting after statement execution processing [ON_CLOSE]
2021-10-16 17:41:14.765 DEBUG 884 --- [nio-8080-exec-3] o.h.e.i.AbstractSaveEventListener : Generated identifier: 3422, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator
2021-10-16 17:41:14.765 TRACE 884 --- [nio-8080-exec-3] o.h.e.i.AbstractSaveEventListener : Saving [com.backend.declarations.repository.entity.PersonEntity#3422]
2021-10-16 17:41:14.769 TRACE 884 --- [nio-8080-exec-3] org.hibernate.engine.spi.ActionQueue : Adding an EntityInsertAction for [com.backend.declarations.repository.entity.PersonEntity] object
2021-10-16 17:41:14.772 TRACE 884 --- [nio-8080-exec-3] org.hibernate.engine.spi.ActionQueue : Adding insert with no non-nullable, transient entities: [EntityInsertAction[com.backend.declarations.repository.entity.PersonEntity#3422]]
2021-10-16 17:41:14.772 TRACE 884 --- [nio-8080-exec-3] org.hibernate.engine.spi.ActionQueue : Adding resolved non-early insert action.
2021-10-16 17:41:14.778 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2021-10-16 17:41:14.871 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.toString]: This method is not transactional.
2021-10-16 17:41:14.951 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.toString]: This method is not transactional.
2021-10-16 17:41:18.392 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : Completing transaction for [com.backend.declarations.service.impl.PersonServiceImpl.savePerson]
2021-10-16 17:41:18.393 TRACE 884 --- [nio-8080-exec-3] org.hibernate.internal.SessionImpl : Closing session [16b4f365-b4f9-4267-bed6-a5057aad25a9]
2021-10-16 17:41:18.393 TRACE 884 --- [nio-8080-exec-3] o.h.e.jdbc.internal.JdbcCoordinatorImpl : Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl@695993a3]
2021-10-16 17:41:18.393 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing JDBC resources
2021-10-16 17:41:18.393 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.LogicalConnectionManagedImpl : Closing logical connection
2021-10-16 17:41:18.394 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing JDBC resources
2021-10-16 17:41:18.395 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.LogicalConnectionManagedImpl : Logical connection closed
主要 Ts 配置:
@Configuration
@EnableJpaRepositories(basePackages = {
"com.backend.auth.repository",
"com.backend.domainoptions.repository",
"com.backend.actionlog.repository",
"com.backend.surveys.repository"
},
entityManagerFactoryRef = "primaryEntityManager",
transactionManagerRef = "primaryTransactionManager")
@EnableTransactionManagement
class PrimaryTsConfiguration {
@Autowired
Environment env;
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManager() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(primaryDataSource());
em.setPackagesToScan(
"com.backend.auth.repository",
"com.backend.domainoptions.repository",
"com.backend.actionlog.repository",
"com.backend.surveys.repository"
);
HibernateJpaVendorAdapter vendorAdapter
= new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto",
env.getProperty("spring.jpa.hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect",
env.getProperty("spring.jpa.hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
@Bean(name = "defaultDs")
@Primary
public DataSource primaryDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("spring.datasource.driverClassName"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
@Bean(name="primaryTransactionManager")
@Autowired
@Primary
DataSourceTransactionManager primaryTransactionManager(@Qualifier("defaultDs") DataSource datasource) {
return new DataSourceTransactionManager(datasource);
}
}
二级TS配置:
@Configuration
@EnableJpaRepositories(basePackages = {
"com.backend.schools.repository",
"com.backend.declarations.repository",
"com.backend.verifications.repository"
},
entityManagerFactoryRef = "secondaryEntityManager",
transactionManagerRef = "secondaryTransactionManager")
@EnableConfigurationProperties(RepositoryProperties.class)
@EnableTransactionManagement
public class SecondaryTmConfiguration {
@Autowired
Environment env;
@Configuration
@PropertySource(factory = YamlPropertySourceFactory.class, value = "datasourceconfig.yml")
static class PropertiesConfiguration {
}
@Bean
public LocalContainerEntityManagerFactoryBean secondaryEntityManager(RepositoryProperties repositoryProperties) {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(secondaryDataSource(repositoryProperties));
em.setPackagesToScan(
"com.backend.schools.repository.entity",
"com.backend.declarations.repository.entity",
"com.backend.verifications.repository.entity"
);
HibernateJpaVendorAdapter vendorAdapter
= new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto",
env.getProperty("spring.jpa.hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect",
env.getProperty("spring.jpa.hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
@Bean(name = "secondDs")
public DataSource secondaryDataSource(RepositoryProperties repositoryProperties) {
System.out.println(repositoryProperties);
DataSourceRouting dataSourceRouting = new DataSourceRouting();
dataSourceRouting.initDatasource(createDataSources(repositoryProperties));
return dataSourceRouting;
}
@Bean(name="secondaryTransactionManager")
@Autowired
DataSourceTransactionManager secondaryTransactionManager(@Qualifier("secondDs") DataSource datasource) {
return new DataSourceTransactionManager(datasource);
}
private List<Pair<String, DataSource>> createDataSources(RepositoryProperties repositoryProperties) {
return repositoryProperties.getDbNumbers().stream()
.map(dbNumber -> createDataSource(dbNumber, repositoryProperties))
.collect(Collectors.toList());
}
private Pair<String, DataSource> createDataSource(String dbNumber, RepositoryProperties repositoryProperties) {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(createDataSourceUrl(dbNumber));
dataSource.setUsername(repositoryProperties.getUsername());
dataSource.setPassword(repositoryProperties.getPassword());
dataSource.setDriverClassName(repositoryProperties.getDriverClassName());
return Pair.of(dbNumber, dataSource);
}
private String createDataSourceUrl(String dbNumber) {
return env.getProperty("spring.custom.datasource.url.prefix") + dbNumber + env.getProperty("spring.custom.datasource.url.suffix");
}
}
为什么它不起作用?
我错过了什么?
好的,问题是 JPA 实体不适用于 DataSourceTransactionManager
。
我改用 JpaTransactionManager
并且效果很好
我有事务服务,我用它来创建一个人并将其保存在数据库中。 问题是提交事务后实体没有保存到数据库中。
起初我以为是 JpaRepository 的错,每次调用方法时它都会打开一个新事务,但据我了解,这些只是打开的单个物理事务中的逻辑事务为我服务。
我使用 Spring Boot 和 Hibernate 连接我的 firebird 数据库。 为此,我配置了两个独立的数据源和事务管理器。 在每个@Transactional 注释中,我指定要使用的事务管理器。 获取数据完美无缺。问题只涉及保存。
我实际上在这里执行了更多操作,但为了示例,我将限制自己只保存实体。 下面的简单示例。
@Transactional("secondaryTransactionManager")
@RequiredArgsConstructor
public class PersonServiceImpl implements PersonService {
private final PersonJpaRepository personJpaRepository;
@Override
public String savePerson() {
var personEntity = new PersonEntity();
personEntity.setName("Slawek");
personEntity.setSurname("Filip");
personEntity.setPersonalNumber("12341234123");
var save = personJpaRepository.save(personEntity);
return save.getName();
}
}
虽然个人实体没有保存在数据库中。有日志
2021-10-16 17:41:13.345 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : Getting transaction for [com.backend.declarations.service.impl.PersonServiceImpl.savePerson]
2021-10-16 17:41:13.772 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.toString]: This method is not transactional.
2021-10-16 17:41:13.967 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.toString]: This method is not transactional.
2021-10-16 17:41:14.716 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2021-10-16 17:41:14.728 DEBUG 884 --- [nio-8080-exec-3] o.s.orm.jpa.EntityManagerFactoryUtils : Opening JPA EntityManager
2021-10-16 17:41:14.728 TRACE 884 --- [nio-8080-exec-3] .i.SessionFactoryImpl$SessionBuilderImpl : Opening Hibernate Session. tenant=null
2021-10-16 17:41:14.729 TRACE 884 --- [nio-8080-exec-3] org.hibernate.internal.SessionImpl : Opened Session [16b4f365-b4f9-4267-bed6-a5057aad25a9] at timestamp: 1634398874728
2021-10-16 17:41:14.735 TRACE 884 --- [nio-8080-exec-3] o.hibernate.event.internal.EntityState : Transient instance of: com.backend.declarations.repository.entity.PersonEntity
2021-10-16 17:41:14.736 TRACE 884 --- [nio-8080-exec-3] o.h.e.i.DefaultPersistEventListener : Saving transient instance
2021-10-16 17:41:14.738 DEBUG 884 --- [nio-8080-exec-3] org.hibernate.SQL : select gen_id( GEN_OSOBY_ID, 1 ) from RDB$DATABASE
2021-10-16 17:41:14.750 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Registering statement [org.firebirdsql.jdbc.FBPreparedStatement@1b6]
2021-10-16 17:41:14.752 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Registering result set [org.firebirdsql.jdbc.FBResultSet@7e70efdc]
2021-10-16 17:41:14.760 DEBUG 884 --- [nio-8080-exec-3] o.h.id.enhanced.SequenceStructure : Sequence value obtained: 3422
2021-10-16 17:41:14.760 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing result set [org.firebirdsql.jdbc.FBResultSet@7e70efdc]
2021-10-16 17:41:14.760 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Closing result set [org.firebirdsql.jdbc.FBResultSet@7e70efdc]
2021-10-16 17:41:14.764 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing statement [org.firebirdsql.jdbc.FBPreparedStatement@1b6]
2021-10-16 17:41:14.764 DEBUG 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : HHH000387: ResultSet's statement was not registered
2021-10-16 17:41:14.764 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Closing prepared statement [org.firebirdsql.jdbc.FBPreparedStatement@1b6]
2021-10-16 17:41:14.764 TRACE 884 --- [nio-8080-exec-3] o.h.e.jdbc.internal.JdbcCoordinatorImpl : Starting after statement execution processing [ON_CLOSE]
2021-10-16 17:41:14.765 DEBUG 884 --- [nio-8080-exec-3] o.h.e.i.AbstractSaveEventListener : Generated identifier: 3422, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator
2021-10-16 17:41:14.765 TRACE 884 --- [nio-8080-exec-3] o.h.e.i.AbstractSaveEventListener : Saving [com.backend.declarations.repository.entity.PersonEntity#3422]
2021-10-16 17:41:14.769 TRACE 884 --- [nio-8080-exec-3] org.hibernate.engine.spi.ActionQueue : Adding an EntityInsertAction for [com.backend.declarations.repository.entity.PersonEntity] object
2021-10-16 17:41:14.772 TRACE 884 --- [nio-8080-exec-3] org.hibernate.engine.spi.ActionQueue : Adding insert with no non-nullable, transient entities: [EntityInsertAction[com.backend.declarations.repository.entity.PersonEntity#3422]]
2021-10-16 17:41:14.772 TRACE 884 --- [nio-8080-exec-3] org.hibernate.engine.spi.ActionQueue : Adding resolved non-early insert action.
2021-10-16 17:41:14.778 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2021-10-16 17:41:14.871 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.toString]: This method is not transactional.
2021-10-16 17:41:14.951 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.toString]: This method is not transactional.
2021-10-16 17:41:18.392 TRACE 884 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : Completing transaction for [com.backend.declarations.service.impl.PersonServiceImpl.savePerson]
2021-10-16 17:41:18.393 TRACE 884 --- [nio-8080-exec-3] org.hibernate.internal.SessionImpl : Closing session [16b4f365-b4f9-4267-bed6-a5057aad25a9]
2021-10-16 17:41:18.393 TRACE 884 --- [nio-8080-exec-3] o.h.e.jdbc.internal.JdbcCoordinatorImpl : Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl@695993a3]
2021-10-16 17:41:18.393 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing JDBC resources
2021-10-16 17:41:18.393 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.LogicalConnectionManagedImpl : Closing logical connection
2021-10-16 17:41:18.394 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing JDBC resources
2021-10-16 17:41:18.395 TRACE 884 --- [nio-8080-exec-3] o.h.r.j.i.LogicalConnectionManagedImpl : Logical connection closed
主要 Ts 配置:
@Configuration
@EnableJpaRepositories(basePackages = {
"com.backend.auth.repository",
"com.backend.domainoptions.repository",
"com.backend.actionlog.repository",
"com.backend.surveys.repository"
},
entityManagerFactoryRef = "primaryEntityManager",
transactionManagerRef = "primaryTransactionManager")
@EnableTransactionManagement
class PrimaryTsConfiguration {
@Autowired
Environment env;
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManager() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(primaryDataSource());
em.setPackagesToScan(
"com.backend.auth.repository",
"com.backend.domainoptions.repository",
"com.backend.actionlog.repository",
"com.backend.surveys.repository"
);
HibernateJpaVendorAdapter vendorAdapter
= new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto",
env.getProperty("spring.jpa.hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect",
env.getProperty("spring.jpa.hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
@Bean(name = "defaultDs")
@Primary
public DataSource primaryDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("spring.datasource.driverClassName"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
@Bean(name="primaryTransactionManager")
@Autowired
@Primary
DataSourceTransactionManager primaryTransactionManager(@Qualifier("defaultDs") DataSource datasource) {
return new DataSourceTransactionManager(datasource);
}
}
二级TS配置:
@Configuration
@EnableJpaRepositories(basePackages = {
"com.backend.schools.repository",
"com.backend.declarations.repository",
"com.backend.verifications.repository"
},
entityManagerFactoryRef = "secondaryEntityManager",
transactionManagerRef = "secondaryTransactionManager")
@EnableConfigurationProperties(RepositoryProperties.class)
@EnableTransactionManagement
public class SecondaryTmConfiguration {
@Autowired
Environment env;
@Configuration
@PropertySource(factory = YamlPropertySourceFactory.class, value = "datasourceconfig.yml")
static class PropertiesConfiguration {
}
@Bean
public LocalContainerEntityManagerFactoryBean secondaryEntityManager(RepositoryProperties repositoryProperties) {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(secondaryDataSource(repositoryProperties));
em.setPackagesToScan(
"com.backend.schools.repository.entity",
"com.backend.declarations.repository.entity",
"com.backend.verifications.repository.entity"
);
HibernateJpaVendorAdapter vendorAdapter
= new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto",
env.getProperty("spring.jpa.hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect",
env.getProperty("spring.jpa.hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
@Bean(name = "secondDs")
public DataSource secondaryDataSource(RepositoryProperties repositoryProperties) {
System.out.println(repositoryProperties);
DataSourceRouting dataSourceRouting = new DataSourceRouting();
dataSourceRouting.initDatasource(createDataSources(repositoryProperties));
return dataSourceRouting;
}
@Bean(name="secondaryTransactionManager")
@Autowired
DataSourceTransactionManager secondaryTransactionManager(@Qualifier("secondDs") DataSource datasource) {
return new DataSourceTransactionManager(datasource);
}
private List<Pair<String, DataSource>> createDataSources(RepositoryProperties repositoryProperties) {
return repositoryProperties.getDbNumbers().stream()
.map(dbNumber -> createDataSource(dbNumber, repositoryProperties))
.collect(Collectors.toList());
}
private Pair<String, DataSource> createDataSource(String dbNumber, RepositoryProperties repositoryProperties) {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(createDataSourceUrl(dbNumber));
dataSource.setUsername(repositoryProperties.getUsername());
dataSource.setPassword(repositoryProperties.getPassword());
dataSource.setDriverClassName(repositoryProperties.getDriverClassName());
return Pair.of(dbNumber, dataSource);
}
private String createDataSourceUrl(String dbNumber) {
return env.getProperty("spring.custom.datasource.url.prefix") + dbNumber + env.getProperty("spring.custom.datasource.url.suffix");
}
}
为什么它不起作用? 我错过了什么?
好的,问题是 JPA 实体不适用于 DataSourceTransactionManager
。
我改用 JpaTransactionManager
并且效果很好