Spring - JdbcTemplate持久化的数据无法被JpaRepository看到

时间:2017-05-09 09:20:07

标签: spring jdbc spring-boot transactions spring-data-jpa

我正在构建一个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数据库?

1 个答案:

答案 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!