使用JPA 2.0编程加载实体类? [英] Programmatically loading Entity classes with JPA 2.0?

查看:129
本文介绍了使用JPA 2.0编程加载实体类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

有没有办法做同样的事情 - 以编程方式加载您的Entity类 - 符合JPA 2.0方式?



这个问题的原因是因为我想动态加载我的实体类,因此不一定以编程方式。

解决方案

在Spring的帮助下,我以符合JPA的方式执行此操作。 / p>

我的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实现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());
设置< String> entityClasses = r.getStore()。getTypesAnnotatedWith(Entity.class.getName());
设置< 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 context xml像这样: / p>

 < bean id =entityManagerFactoryclass =org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean> 
< property name =dataSourceref =dataSource/>
< property name =jpaVendorAdapter>
< bean class =org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter>
< property name =showSqlvalue =false/>
< property name =generateDdlvalue =true/>
< property name =databasePlatformvalue =org.hibernate.dialect.MySQL5InnoDBDialect/>
< / bean>
< / property>
< property name =persistenceUnitNamevalue =GenericPersistenceUnit/>
< property name =persistenceXmlLocationvalue =classpath:META-INF / persistence.xml/>新新旗200 200 200 200 200 200 -40 200 200 -40 200 200 -40 200 200 -40 200 200 -40 200 200 -40 200 200 -40 200 200 X-
< list>
< bean class =com.austinmichael.core.repository.ReflectionsPersistenceUnitPostProcessor>
< property name =reflectionsRootvalue =com.austinmichael/>
< / bean>
< / list>
< / property>
< / bean>

请注意在 ReflectionsPersistenceUnitPostProcessor 中注册persistenceUnitPostProcessors设置。



就是这样。在类路径中添加了具有JPA实体或 MappedSuperclass 注释的类。我必须给出反思一个包名称的前缀来扫描,这就是为什么 com.austinmichael 在那里。如果您的实体不共享通用包名称前缀,则可以使用不同的包名前缀注册第二个 ReflectionsPersistenceUnitPostProcessor



但是,这是JPAVendor不可知论。


With Hibernate you can load your Entity classes as:

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

Is there a way to do the same thing - programmatically loading your Entity classes - in a JPA 2.0 compliant way?

The reason for this question is because I'd like to dynamically load my Entity classes, thus not necessarily programmatically.

解决方案

With the help of Spring I did this in a JPA compliant way.

My "persistence.xml" looks empty, with no entities listed within the <persistence-unit> element.

I then wrote a class that implemented PersistenceUnitPostProcessor like so:

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;
    }
}

Then I adjusted my spring context xml like this:

<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>

Note the registration of the ReflectionsPersistenceUnitPostProcessor in the persistenceUnitPostProcessors setting.

And that's it. Every class with a JPA Entity or MappedSuperclass annotation on the classpath is added to the classpath. I had to give reflections the prefix of a package name to scan through which is why com.austinmichael is there at all. You could register a second ReflectionsPersistenceUnitPostProcessor with a different package name prefix if you want if your entities don't share a common package name prefix.

But, this is now JPAVendor agnostic.

这篇关于使用JPA 2.0编程加载实体类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆