使用JPA 2.0编程加载实体类? [英] Programmatically loading Entity classes with 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屋!