24

Hibernate を使用すると、Entityクラスを次のようにロードできます。

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

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

この質問の理由は、クラスを動的にロードしたいためEntity、必ずしもプログラム的にではありません。

4

3 に答える 3

28

Spring の助けを借りて、JPA 準拠の方法でこれを行いました。

<persistence-unit>私の「persistence.xml」は空に見え、要素内にエンティティがリストされていません。

次に、次のように 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>

ReflectionsPersistenceUnitPostProcessorpersistenceUnitPostProcessors 設定での の登録に注意してください。

以上です。クラスパスにJPA エンティティまたはMappedSuperclassアノテーションを持つすべてのクラスがクラスパスに追加されます。リフレクションにパッケージ名のプレフィックスを付けてスキャンする必要com.austinmichaelがあったため、まったく存在しません。ReflectionsPersistenceUnitPostProcessorエンティティが共通のパッケージ名プレフィックスを共有していない場合は、必要に応じて別のパッケージ名プレフィックスを使用して秒を登録できます。

しかし、これは現在、JPAVendor に依存しません。

于 2011-12-27T20:04:00.153 に答える
5

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

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

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

また、より多くのコード サンプルについては、この最近のスレッドを参照してください (API は少し冗長に見えます)。

参考文献

于 2010-05-23T17:11:11.480 に答える
3

そのようなオプションはないと思います.JPAはエンティティのクラスパスをスキャンするか、persistence.xmlにエンティティクラスを明示的にリストすることをサポートしています. ただし、永続化プロバイダーとして休止状態を使用しているため、いつでも休止状態のコードに頼ることができます。HibernateEntityManagerHibernateEntityManagerFactoryクラスを見てください。エンティティ マネージャ ファクトリとエンティティ マネージャをそれらにキャストして、通常の休止状態にすることができます。

于 2010-05-15T04:51:55.350 に答える