2017-05-09 14 views
0

JDBCを介した永続化とJPA/Hibernate経由の選択/読み込みが必要なSpring起動アプリケーションを構築しています。 SpringのJdbcTemplateとSpring DataのJpaRepositoryを使用して、これらのタイプの操作を実装しました。Spring - JdbcTemplateによって永続化されたデータがJpaRepositoryによって表示されない

JdbcTemplateを使用していても、同じデータソースを共有していてもJpaRepository経由でデータを見ることができません。 JdbcTemplateを使用すると、データを読み取ることができます。

注:私は2つのデータソースを使用しています。 @Primaryアノテーションを持たない別のクラスでは、独自のエンティティマネージャファクトリとトランザクションマネージャを使用しているため、Springブートのデフォルトの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

私は、SQLを表示し、手動で書かれたJDBCテンプレートコードでJPAリポジトリから実行されているHibernate生成SQLを比較するために、Hibernateのログインを有効にします。 パーシスタンスとクエリコードも投稿できますか? なぜ手動JDBCを使い続けているのか魅力的です。 – PaulNUK

+0

LocalContainerEntityManagerFactoryBeanにvendoradapterを指定していません。それが原因である可能性があります – pvpkiran

+0

あなたがそれを読むことができないという事実はおそらくあなたがそれをコミットしていないか、2つのトランザクションを持っていることを意味します。他のトランザクションからコミットされていないデータを読み取ることはできません。また、Springブートを使用している場合は、すべての手動構成が必要ですか? –

答えて

0

上記の設定は正しいです!

JdbcTemplateの呼び出しには、スキーマの所有者が接頭辞として含まれていたという問題がありました。たとえば :

select * from I_AM_SCHEMA.KILL_ME 

しかし、私は@Entityアノテーションとエンティティオブジェクト上@Table注釈の両方を持っていた唯一のテーブル名を指定しました! 例:

@Entity 
@Table(name = "KILL_ME") 

だから、我々はJdbcTemplateで一つのテーブルに書き込むが、接頭辞を逃す原因私たちにJPA/Hibernateのを経由して完全に異なる他のテーブルから読んでいました。

正しい修正は@Entityアノテーションでエンティティ名を接頭辞にした:

DONE
@Entity("I_AM_SCHEMA.KILL_ME") 

関連する問題