Hibernateを使用すると、Entity
クラスを次のようにロードできます。
sessionFactory = new AnnotationConfiguration()
.addPackage("test.animals")
.addAnnotatedClass(Flight.class)
.addAnnotatedClass(Sky.class)
.addAnnotatedClass(Person.class)
.addAnnotatedClass(Dog.class);
同じこと(プログラムでエンティティクラスをロードする)をJPA 2.0準拠の方法で行う方法はありますか?
この質問の理由は、動的にEntity
クラスをロードしたいので、必ずしもプログラムでロードする必要はないからです。
Springの助けを借りて、私はこれをJPA準拠の方法で行いました。
「persistence.xml」は空に見え、<persistence-unit>
要素内にエンティティがリストされていません。
次に、次のようにPersistenceUnitPostProcessorを実装するクラスを作成しました。
import Java.util.Set;
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;
import org.reflections.Reflections;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
public class ReflectionsPersistenceUnitPostProcessor implements PersistenceUnitPostProcessor {
private String reflectionsRoot;
private Logger log = LoggerFactory.getLogger(ReflectionsPersistenceUnitPostProcessor.class);
@Override
public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) {
Reflections r = new Reflections(this.reflectionsRoot, new TypeAnnotationsScanner());
Set<String> entityClasses = r.getStore().getTypesAnnotatedWith(Entity.class.getName());
Set<String> mappedSuperClasses = r.getStore().getTypesAnnotatedWith(MappedSuperclass.class.getName());
for (String clzz : mappedSuperClasses)
{
pui.addManagedClassName(clzz);
}
for (String clzz : entityClasses)
{
pui.addManagedClassName(clzz);
}
}
public String getReflectionsRoot() {
return reflectionsRoot;
}
public void setReflectionsRoot(String reflectionsRoot) {
this.reflectionsRoot = reflectionsRoot;
}
}
次に、Springコンテキストxmlを次のように調整しました。
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
</bean>
</property>
<property name="persistenceUnitName" value="GenericPersistenceUnit"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
<property name="persistenceUnitPostProcessors">
<list>
<bean class="com.austinmichael.core.repository.ReflectionsPersistenceUnitPostProcessor">
<property name="reflectionsRoot" value="com.austinmichael"/>
</bean>
</list>
</property>
</bean>
ReflectionsPersistenceUnitPostProcessor
がpersistenceUnitPostProcessors設定に登録されていることに注意してください。
以上です。クラスパスにJPAエンティティまたはMappedSuperclass
アノテーションが付いているすべてのクラスが、クラスパスに追加されます。スキャンするパッケージ名のプレフィックスをリフレクションに指定する必要がありました。そのため、com.austinmichael
がまったく存在しません。エンティティが共通のパッケージ名プレフィックスを共有しない場合は、必要に応じて、2番目のReflectionsPersistenceUnitPostProcessor
を別のパッケージ名プレフィックスで登録できます。
しかし、これは現在JPAVendorに依存していません。
同じこと(プログラムでエンティティクラスをロードする)をJPA 2.0準拠の方法で行う方法はありますか?
いいえ、これはJPAでサポートされていないため、プロバイダー固有の方法でこれを行う必要があります。 James Sutherlandは、EclipseLinkのプロセスを このスレッド で次のように説明しました。
EclipseLink
ServerSession
にEntityManagerFactoryImpl
(getServerSession()
)からアクセスし、その 'addDescriptor(ClassDescriptor)
またはaddDescriptors()
APIを使用してEclipseLinkClassDescriptor
を追加します。 JPAアノテーションまたはorm.xmlからのロードはより困難になるため、ClassDescriptor
メタデータオブジェクトを自分で直接構築する(またはマッピングワークベンチを使用して作成する)必要があります。
また、これを見てください より最近のスレッド より多くのコードサンプル(APIは少し冗長に見えます)。
そのようなオプションはないと思います-JPAは、エンティティのクラスパスのスキャン、またはpersistence.xmlでのエンティティクラスの明示的なリストをサポートしています。ただし、永続化プロバイダーとしてHibernateを使用しているため、いつでもHibernateコードに頼ることができます。 HibernateEntityManager
クラスとHibernateEntityManagerFactory
クラスをご覧ください。エンティティマネージャファクトリとエンティティマネージャをそれらにキャストして、通常の休止状態の処理を実行できます。