【发布时间】:2017-05-09 09:20:06
【问题描述】:
我正在构建一个 Spring Boot 应用程序,该应用程序需要通过 JDBC 持久化并通过 JPA/Hibernate 进行选择/读取。我已经使用 Spring 的 JdbcTemplate 和 Spring Data 的 JpaRepository 实现了这两种类型的操作。
在我坚持使用 JdbcTemplate 后,我无法通过 JpaRepository 查看数据,即使它们共享相同的数据源。如果我使用 JdbcTemplate,我可以读取数据。
注意:我正在使用两个数据源。一个是在另一个类中配置的,没有使用它自己的实体管理器工厂和事务管理器的 @Primary 注释,这就是为什么我需要使用 Spring Boot 的默认 bean 术语“transactionManager”和“entityManagerFactory”在下面显式定义它。
以下是我的主 bean 的嵌入式数据库配置:
@Configuration
@EnableJpaRepositories(basePackages = {"com.repository"})
public class H2DataSourceConfiguration {
private static final Logger log = LoggerFactory.getLogger(H2DataSourceConfiguration.class);
@Bean(destroyMethod = "shutdown")
@Primary
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.setName("dataSource")
.build();
}
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("com.my.domain", "org.springframework.data.jpa.convert.threeten")
.build();
}
@Bean
@Primary
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(entityManagerFactory);
return jpaTransactionManager;
}
}
持久性发生在与读取数据不同的事务中,但是它们共享相同的服务。 这两个操作都发生在 @Transactional 注释中。两个存储库 bean 都在同一个服务中指定,并且还包含 @Transactional 注释。该服务如下所示:
@Service
@Transactional
public class MyServiceImpl implements MyService {
private static final Logger log = LoggerFactory.getLogger(MyServiceImpl.class);
@Autowired
private MyJpaRepository myJpaRepository;
@Autowired
private MyJdbcRepository myJdbcRepository;
...
}
MyJdbcRepositoryImpl.java:
@Repository
@Transactional(propagation = Propagataion.MANDATORY)
public class MyJdbcRepositoryImpl implements MyJdbcRepository {
@Autowired
private NamedParameterJdbcTemplate jdbcTemplate;
// methods within here all use jdbcTemplate.query(...)
}
MyJpaRepository.java:
@Repository
@Transactional(propagation = Propagataion.MANDATORY)
public interface AcquisitionJpaRepository extends JpaRepository<AcquisitionEntity, Long> {
}
jdbctemplate 调用是否有可能保存到不同的 h2 数据库?
【问题讨论】:
-
我会打开登录 hibernate 以显示 SQL,并将从 JPA 存储库运行的 hibernate 生成的 SQL 与您手动编写的 JDBC 模板代码进行比较。您能否也发布您的持久性和查询代码。很想知道您为什么坚持使用手动 JDBC。
-
您没有为 LocalContainerEntityManagerFactoryBean 指定任何供应商适配器。可能是这个原因
-
您无法阅读它的事实可能意味着您尚未提交它或有 2 个事务。您不能从另一个事务中读取未提交的数据。另外,如果您使用的是 Spring Boot,为什么要手动配置?
-
为什么要手动创建JpaTransactionManager?看起来您有两个独立的交易。
-
@PaulNUK 坚持使用 JDBC,因为我们的音量级别需要它的速度。使用 JPA 阅读,因为我们需要流式传输一些结果并对其他结果进行分页。
标签: spring jdbc spring-boot transactions spring-data-jpa