JPA 2.0を使用してエンティティクラスをプログラムでロードしますか?

StackOverflow https://stackoverflow.com/questions/2838634

質問

Hibernate を使用すると、 Entity 次のようなクラス:

sessionFactory = new AnnotationConfiguration()
                    .addPackage("test.animals")
                    .addAnnotatedClass(Flight.class)
                    .addAnnotatedClass(Sky.class)
                    .addAnnotatedClass(Person.class)
                    .addAnnotatedClass(Dog.class);

JPA 2.0に準拠した方法で、同じこと、つまりエンティティクラスをプログラムでロードすることを行う方法はありますか?

この質問の理由は、次のことをしたいからです。 動的に 私のものをロードしてください Entity したがって、必ずしもプログラム的にクラスを作成する必要はありません。

役に立ちましたか?

解決

春Iの助けを借りて、 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;
    }
}

そして、私はこのように私の春のコンテキスト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>

設定persistenceUnitPostProcessorsにReflectionsPersistenceUnitPostProcessorの登録を注意してください。

そして、それはそれです。 JPAエンティティまたはクラスパス上MappedSuperclass注釈を持つすべてのクラスは、クラスパスに追加されます。私はcom.austinmichaelがすべてである理由である、それを通してスキャンに反射パッケージの名前の接頭辞を与えなければなりませんでした。あなたがしたい場合は、あなたのエンティティは、共通のパッケージ名の接頭辞を共有していない場合は、別のパッケージ名の接頭辞を持つ二ReflectionsPersistenceUnitPostProcessorを登録することができます。

しかし、これは今JPAVendorとらわれないです。

他のヒント

JPA 2.0に準拠した方法で、同じこと、つまりエンティティクラスをプログラムでロードすることを行う方法はありますか?

いいえ、これは JPA ではサポートされていないため、プロバイダー固有の方法でこれを行う必要があります。James Sutherland は、EclipseLink のプロセスについて次のように説明しています。 このスレッド このような:

EclipseLinkにアクセスできます ServerSession から EntityManagerFactoryImpl (getServerSession())、その'を使用します addDescriptor(ClassDescriptor) または addDescriptors() EclipseLinkを追加するためのAPI ClassDescriptor. 。を構築する必要があります。 ClassDescriptor JPA アノテーションまたは orm.xml からロードするのはより困難であるため、メタデータ オブジェクトを自分で直接 (またはマッピング ワークベンチを使用して作成して) 作成します。

こちらもご覧ください もっと最近のスレッド さらにコードサンプルを参照してください (API は少し冗長に見えます)。

参考文献

私はそのようなオプションがあるとは思わない - JPAがサポートするエンティティのためのクラスパスをスキャンするか、明示的にpersistence.xmlでエンティティクラスを一覧表示します。あなたが永続プロバイダとして休止状態を使用しているので、しかし、あなたは常にコードを休止状態にするために頼ることができます。 HibernateEntityManagerHibernateEntityManagerFactoryクラスを見てみましょう。あなたがそれらにエンティティマネージャの工場やエンティティマネージャをキャストし、通常の休止状態のものを行うことができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top