我正在构建一个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数据库?
答案 0 :(得分:1)
以上配置是正确的!
问题是JdbcTemplate调用将架构所有者作为前缀。 例如:
select * from I_AM_SCHEMA.KILL_ME
但是,我在实体对象上同时拥有@Entity注释和@Table注释,并且只指定了表名! 例如:
@Entity
@Table(name = "KILL_ME")
所以,我们用JdbcTemplate写了一个表,但是由于我们错过了前缀而从JPA / Hibernate读取了一个完全不同的其他表。
正确的解决方法是在@Entity注释中为实体名称添加前缀:
@Entity("I_AM_SCHEMA.KILL_ME")
DONE!