以编程方式使用JPA 2.0加载实体类?
使用Hibernate,您可以将Entity
类加载为:
sessionFactory = new AnnotationConfiguration() .addPackage("test.animals") .addAnnotatedClass(Flight.class) .addAnnotatedClass(Sky.class) .addAnnotatedClass(Person.class) .addAnnotatedClass(Dog.class);
有没有办法做同样的事情 – 以编程方式加载您的实体类 – 以符合JPA 2.0的方式?
这个问题的原因是因为我想动态加载我的Entity
类,因此不一定以编程方式。
在Spring的帮助下,我以符合JPA的方式完成了这项工作。
我的“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 entityClasses = r.getStore().getTypesAnnotatedWith(Entity.class.getName()); Set 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:
请注意在persistenceUnitPostProcessors设置中注册ReflectionsPersistenceUnitPostProcessor
。
就是这样。 在类路径MappedSuperclass
每个具有JPA实体或MappedSuperclass
注释的类添加到类路径中。 我必须给出思考包装名称的前缀来扫描,这就是com.austinmichael
在那里的原因。 如果您希望实体不共享公共包名称前缀,则可以使用不同的包名称前缀注册第二个ReflectionsPersistenceUnitPostProcessor
。
但是,现在这是JPAVendor不可知论者。
有没有办法做同样的事情 – 以编程方式加载您的实体类 – 以符合JPA 2.0的方式?
不,JPA不支持此function,因此您必须以提供程序特定的方式执行此操作。 James Sutherland在这个线程中描述了EclipseLink的过程,如下所示:
您可以从
EntityManagerFactoryImpl
(getServerSession()
)访问EclipseLinkServerSession
,并使用其’addDescriptor(ClassDescriptor)
或addDescriptors()
API来添加EclipseLinkClassDescriptor
。 您需要自己直接构建ClassDescriptor
元数据对象(或使用Mapping Workbench来创建它们),因为从JPA注释或orm.xml加载会更加困难。
还要看一下这个更新的线程以获取更多代码示例(API看起来有点冗长)。
参考
- 回复:[eclipselink-users]关闭得到它。 只是一点帮助
- Re:JPA:以编程方式向EntityManagerFactory添加实体
我不认为有这样的选择 – JPA支持扫描实体的类路径或在persistence.xml中显式列出实体类。 因为你使用hibernate作为持久性提供程序,所以你总是可以使用hibernate代码。 看看HibernateEntityManager
和HibernateEntityManagerFactory
类。 您可以将实体管理器工厂和实体管理器强制转换为它们,并执行常用的hibernate工作。