wen*_*wen 22 java entities dynamic jpa-2.0
使用Hibernate,您可以将Entity类加载为:
sessionFactory = new AnnotationConfiguration()
.addPackage("test.animals")
.addAnnotatedClass(Flight.class)
.addAnnotatedClass(Sky.class)
.addAnnotatedClass(Person.class)
.addAnnotatedClass(Dog.class);
Run Code Online (Sandbox Code Playgroud)
有没有办法做同样的事情 - 以编程方式加载您的实体类 - 以符合JPA 2.0的方式?
这个问题的原因是因为我想动态加载我的Entity类,因此不一定以编程方式.
小智 27
在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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我像这样调整了我的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>
Run Code Online (Sandbox Code Playgroud)
请注意ReflectionsPersistenceUnitPostProcessorpersistenceUnitPostProcessors设置中的注册.
就是这样.MappedSuperclass在类路径中将每个具有JPA实体或注释的类添加到类路径中.我必须给出思考包名称的前缀以便扫描,这就是为什么com.austinmichael存在的原因.ReflectionsPersistenceUnitPostProcessor如果您的实体不共享公共包名称前缀,您可以使用不同的包名称前缀注册第二个.
但是,现在这是JPAVendor不可知论者.
有没有办法做同样的事情 - 以编程方式加载您的实体类 - 以符合JPA 2.0的方式?
不,JPA不支持此功能,因此您必须以提供程序特定的方式执行此操作.James Sutherland在这个线程中描述了EclipseLink的过程,如下所示:
您可以
ServerSession从EntityManagerFactoryImpl(getServerSession())访问EclipseLink ,并使用其'addDescriptor(ClassDescriptor)或addDescriptors()API来添加EclipseLinkClassDescriptor.您将需要ClassDescriptor自己直接构建元数据对象(或使用Mapping Workbench来创建它们),因为从JPA注释或orm.xml加载会更加困难.
还要看一下这个更新的线程以获取更多代码示例(API看起来有点冗长).