私は命令でそれを知っています:
Persistence.createEntityManagerFactory("persistence-unit-name");
JPA永続化メカニズムは「persistence.xml」ファイルを読み取り、「persistence-unit-name」という永続性ユニットを探し、それに基づいてEntityManagerFactoryを構築します。
私の質問は、JPAをどのように強制することができますか"persistence.xml"とは異なるファイルを取得 ??たとえば、「persistence-test.xml」。
これを行うための標準化されたJPA方法はありませんが、個々のJPAプロバイダーが方法を提供する場合があります。メインとテストで異なるクラスパスを使用する標準的な方法を提案します。
たとえば、Mavenを使用していて、2つのMETA-INF/persistence.xml
ファイルがあり、1つはsrc/main/resources
に、もう1つはsrc/test/resources
にある場合、テストはsrc/test/resources
にあるファイルを取得します。クラスパス内のメインクラス/リソースの前にテストクラス/リソースを置きます。同様の方法で動作するようにAntを簡単に構成できます。
より高度なロジックが必要な場合は、 SpringのJPAサポート の使用を検討してください。 複数のpersistence.xmlファイルの統合 などの高度な状況に対処できます。
EclipseLinkでは、次のことができます。
Properties pros = new Properties();
pros.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML,
"META-INF/persistence-alternative.xml");
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("pu-name", pros);
できないと思います。これを行う長い方法は次のとおりです。
persistence-test.xml
_を読み取り、_Map<String, String>
_プロパティをレンダリングするファクトリを作成します。Persistence.createEntityManagerFactory(persistenceUnitName, Map properties)
を呼び出します。これにより、_persistence.xml
_からではなく、properties
マップから読み取ります。したがって、2つの別々のpersistence.xml
ファイルが必要です。 1つは実稼働構成でのみ読み取り、もう1つはテストで読み取る必要があります。アイデアはプロダクションの名前変更または非表示ファイルです。
戦争解
persistence.xml
をsrc\main\resources\META-INF\
に含めないでください。代わりにsrc\main\webapp\WEB-INF\classes\META-INF\
に入れてください。これはファイルが存在する場所であり、この場所ではテストからは見えません。
このソリューションは私にとってGradle環境で機能しますが、他のソリューションでも機能することを期待しています。
Jarソリューション
製品ファイルの名前をpersistence-ee.xml
に変更します。これでテスト構成が完了しました。生産のために、我々はいくつかの処理を採用しなければなりません。それぞれの環境には独自の方法があるかもしれません、それが私がgradleでそれをする方法です:
tasks.withType(Jar) {
rename { fileName ->
fileName == "persistence-ee.xml" ? "persistence.xml" : fileName;
}
}
私のアプリケーションでは、プロダクション用のpersistence.xml
ファイルはデプロイメント時にのみ必要です。つまり、jar/warパッケージにあります。そして、これらはこのファイルが表示される唯一の場所です。ダブルpersistence
がないと、データベースを起動できませんでした。主な理由はjta-data-source
を使用することでした。もう1つは、2つの個別の名前付き永続化ユニットです。
OpenEJBを使用してテストを実行している場合、希望するJPAプロバイダーを使用して、希望どおりの操作を実行できます。ここで同様の質問と関連する回答:
mavenにmain/resources/persistence.xmlを無視してtest/...を優先するように指示する方法
次のように、Springでpersistence.xmlをまったく使用せずにHibernateを構成できます。
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean()
{
Map<String, Object> properties = new Hashtable<>();
properties.put("javax.persistence.schema-generation.database.action",
"none");
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect"); //you can change this if you have a different DB
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(adapter);
factory.setDataSource(this.springJpaDataSource());
factory.setPackagesToScan("package name");
factory.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
factory.setValidationMode(ValidationMode.NONE);
factory.setJpaPropertyMap(properties);
return factory;
}
Persistence.xmlを使用していないので、データソースを設定する上記のメソッドで指定したDataSourceを返すBeanを作成する必要があります。
@Bean
public DataSource springJpaDataSource()
{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl("jdbc:mysql://localhost/SpringJpa");
dataSource.setUsername("tomcatUser");
dataSource.setPassword("password1234");
return dataSource;
}
次に、この構成ファイルに対して@EnableTransactionManagement
アノテーションを使用します。次に、そのアノテーションを配置するときに、最後のBeanを1つ作成する必要があります。
@Bean
public PlatformTransactionManager jpaTransactionManager()
{
return new JpaTransactionManager(
this.entityManagerFactoryBean().getObject());
}
ここで、DBを処理するメソッドに対して@Transactional
アノテーションを使用することを忘れないでください。
最後に、リポジトリにEntityManager
を注入することを忘れないでください(このリポジトリクラスには@Repository
アノテーションが必要です)。