使用 Hibernate Unmanaged JPA 在 Equinox OSGI 框架中获取 EntityManagerFactory
Posted
技术标签:
【中文标题】使用 Hibernate Unmanaged JPA 在 Equinox OSGI 框架中获取 EntityManagerFactory【英文标题】:Getting EntityManagerFactory in an Equinox OSGI Framework using Hibernate Unmanaged JPA 【发布时间】:2013-12-16 02:07:42 【问题描述】:我正在使用 Equinox Eclipse 和 Hibernate/JPA 开发 两个 OSGI 包,试图使用 Unmanaged JPA 持久化一个实体强>。
第一个包:“Testhibernate”是一个包,它从休眠 jar 中导出所有包,并具有一个注册 OSGI 服务并使用的激活器“org.hibernate.osgi.HibernateBundleActivator” Equinox 标记 Eclipse-BuddyPolicy: 已注册。
第二个包:“TesthibernateConfigDAO”只是对第一个包有一个依赖项,并且在 Manifest.mf 文件中具有标签 Eclipse-RegisterBuddy: Testhibernate 以链接 persistence.xml 文件。
当我在 OSGI Equinox 容器中同时运行这两个错误时,如果我使用以下方法:
emf = Persistence.createEntityManagerFactory("PersistenceProcessDataUnit");
然后我得到 EntityManagerFactory 并将我的实体直接保存在数据库中,一切都OK。
但是我在官方hibernatewebsite看了下:
17.4.3。获取EntityMangerFactory
hibernate-osgi 使用 JPA 注册一个 OSGi 服务 PersistenceProvider 接口名称,它引导并创建一个 EntityManagerFactory 特定于 OSGi 环境。至关重要的是 您的 EMF 是通过服务获得的,而不是创建它 手动。该服务处理 OSGi 类加载器,发现 扩展点、扫描等。手动创建一个 EntityManagerFactory 保证在运行时不工作!
有关如何发现和使用服务的示例,请参阅 unmanaged-jpa QuickStart 的 HibernateUtil.java。
所以我尝试用这个来获取 EntityManagerFactory:
Bundle thisBundle = FrameworkUtil.getBundle( HibernateUtil.class );
BundleContext context = thisBundle.getBundleContext();
ServiceReference serviceReference = context.getServiceReference( PersistenceProvider.class.getName() );
PersistenceProvider persistenceProvider = (PersistenceProvider) context.getService( serviceReference );
emf = persistenceProvider.createEntityManagerFactory( "PersistenceProcessDataUnit", null );
我已经对此进行了调试,我只是得到了服务和 persistenceProvider 对象,但是当我执行最后一次尝试获取 EntityManagerFactory 时,我得到了错误:
org.osgi.framework.BundleException: 异常 testhibernateconfigdao.HibernateJpaActivator.start() 的 bundle 测试休眠配置DAO。在 org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:734) 在 org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683) 在 org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381) 在 org.eclipse.osgi.framework.internal.core.AbstractBundle.resume(AbstractBundle.java:390) 在 org.eclipse.osgi.framework.internal.core.Framework.resumeBundle(Framework.java:1176) 在 org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:559) 在 org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:544) 在 org.eclipse.osgi.framework.internal.core.StartLevelManager.incFWSL(StartLevelManager.java:457) 在 org.eclipse.osgi.framework.internal.core.StartLevelManager.doSetStartLevel(StartLevelManager.java:243) 在 org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:438) 在 org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:1) 在 org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) 在 org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340) 原因:javax.persistence.PersistenceException:无法在以下位置配置 EntityManagerFactory org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:387) 在 org.hibernate.osgi.OsgiPersistenceProvider.createEntityManagerFactory(OsgiPersistenceProvider.java:83) 在 de.test.HibernateUtil.getEntityManagerFactory(HibernateUtil.java:29) 在 de.test.HibernateUtil.getEntityManager(HibernateUtil.java:18) 在 testhibernateconfigdao.HibernateJpaActivator.start(HibernateJpaActivator.java:24) 在 org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711) 在 java.security.AccessController.doPrivileged(Native Method) 在 org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702) ... 12 更多原因:java.lang.NullPointerException at org.hibernate.osgi.OsgiScanner.getFilesInJar(OsgiScanner.java:112) 在 org.hibernate.ejb.Ejb3Configuration.addScannedEntries(Ejb3Configuration.java:506) 在 org.hibernate.ejb.Ejb3Configuration.addMetadataFromScan(Ejb3Configuration.java:477) 在 org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:363) ... 19 更多
我花了超过 3 天的时间阅读官方文档,但我不明白这是什么问题。
【问题讨论】:
【参考方案1】:您的设置不起作用。如果可以从创建实体管理器工厂的代码中访问带有单元描述的 persistence.xml,则只能创建 EMF。在这种情况下,您可以在不包含 persistence.xml 的包中创建工厂。 NPE 可能是由于在 BundleWiring.listResources 的休眠代码中缺少空检查(当然是一个错误),但这仅仅是无法访问持久性单元描述文件的结果。
您应该在 TestHibernate 包中创建实体管理器工厂并将 EMF 注册为服务。然后,DAO 包可以查找此服务并执行其操作。
顺便说一句:这也是 OSGi 兼容解决方案在 OSGi 规范下的工作方式。我建议查看Gemini JPA 下载中的示例并阅读与JPA 和JNDI 相关的OSGi 规范(通过OSGi Alliance 站点下载)。但也许你已经这样做了。
【讨论】:
首先非常感谢您的回答,我会尝试这种方式。但我认为这是可能的,因为我包含了子句 Eclipse-RegisterBuddy: Testhibernate 所以 Testhibernate 可以看到 persistence.xml 文件在 TesthibernateConfigDAO 我可以用第一种方法持久化对象。我在 OSGI Equinox 只有几天!!!非常感谢您的帮助!!!【参考方案2】:在 Equinox Osgi 中尝试使用休眠几天后,我明白了。我在 Hibernate 论坛中创建了一个帖子,您可以去那里:
https://forum.hibernate.org/viewtopic.php?f=1&t=1029974&p=2473673#p2473673
基本上你需要一步一步地设置你需要的每个包,并且更新到 Hibernate 4.3.0 版本并注意你的包在运行时的顺序!!
【讨论】:
以上是关于使用 Hibernate Unmanaged JPA 在 Equinox OSGI 框架中获取 EntityManagerFactory的主要内容,如果未能解决你的问题,请参考以下文章
无法为 Unmanaged<AnyObject> 调用初始化程序?迅速没有争论
如何从 CGColorSpace 获得 Unmanaged<CGColorSpace>?
Google Play开发者控制台中未提供UnManaged选项
DllImport Unmanaged, Non .NET Dll to .NET Project 表示 Char * 和 Void __StdCall