OSGi 中的 Hibernate 和 H2,缺少 Persistence Provider
Hibernate & H2 in OSGi, Persistence Provider missing
我正在开发一个需要数据库的 OSGi 应用程序。
我选择为我的数据库使用 H2 和 Hibernate。
如何相信 EntityManager 找不到名称为 "test" 的持久性文件。我不相信 PersistenceProvider 不是 运行。当 运行 没有 OSGI 但作为 MavenProject 我没有得到这个错误。
这是控制台输出:
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
osgi> ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
Initial SessionFactory creation failed.javax.persistence.PersistenceException: No Persistence provider for EntityManager named test
!SESSION 2015-05-11 09:22:14.196 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.8.0_25
java.vendor=Oracle Corporation
BootLoader constants: OS=macosx, ARCH=x86_64, WS=cocoa, NL=de_DE
Command-line arguments: -dev file:/Users/christianverdion/Documents/workspace/HibernateH2OSGi/.metadata/.plugins/org.eclipse.pde.core/HibernateH2OSGi/dev.properties -os macosx -ws cocoa -arch x86_64 -consoleLog -console
!ENTRY hibernateh2osgi 4 0 2015-05-11 09:22:16.029
!MESSAGE FrameworkEvent ERROR
!STACK 0
org.osgi.framework.BundleException: Exception in hibernateh2osgi.Activator.start() of bundle hibernateh2osgi.
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:792)
at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:721)
at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:936)
at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:319)
at org.eclipse.osgi.container.Module.doStart(Module.java:571)
at org.eclipse.osgi.container.Module.start(Module.java:439)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1582)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1562)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1533)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1476)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
Caused by: java.lang.ExceptionInInitializerError
at hibernateh2osgi.EntityManagerUtil.<clinit>(EntityManagerUtil.java:16)
at hibernateh2osgi.DataProviderImpl.<init>(DataProviderImpl.java:15)
at hibernateh2osgi.Activator.start(Activator.java:32)
at org.eclipse.osgi.internal.framework.BundleContextImpl.run(BundleContextImpl.java:771)
at org.eclipse.osgi.internal.framework.BundleContextImpl.run(BundleContextImpl.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:764)
... 12 more
Caused by: javax.persistence.PersistenceException: No Persistence provider for EntityManager named test
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
at hibernateh2osgi.EntityManagerUtil.<clinit>(EntityManagerUtil.java:12)
... 18 more
Root exception:
java.lang.ExceptionInInitializerError
at hibernateh2osgi.EntityManagerUtil.<clinit>(EntityManagerUtil.java:16)
at hibernateh2osgi.DataProviderImpl.<init>(DataProviderImpl.java:15)
at hibernateh2osgi.Activator.start(Activator.java:32)
at org.eclipse.osgi.internal.framework.BundleContextImpl.run(BundleContextImpl.java:771)
at org.eclipse.osgi.internal.framework.BundleContextImpl.run(BundleContextImpl.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:764)
at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:721)
at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:936)
at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:319)
at org.eclipse.osgi.container.Module.doStart(Module.java:571)
at org.eclipse.osgi.container.Module.start(Module.java:439)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1582)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1562)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1533)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1476)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
Caused by: javax.persistence.PersistenceException: No Persistence provider for EntityManager named test
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
at hibernateh2osgi.EntityManagerUtil.<clinit>(EntityManagerUtil.java:12)
... 18 more
!ENTRY org.eclipse.osgi 4 0 2015-05-11 09:22:16.239
!MESSAGE Bundle hibernateh2osgi_1.0.0.qualifier [36] is not active.
我的 Manifest.MF 文件如下所示:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Hibernateh2osgi
Bundle-SymbolicName: hibernateh2osgi
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: hibernateh2osgi.Activator
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Meta-Persistence: META-INF/persistence.xml
Import-Package: javax.persistence;version="2.1.0",
org.eclipse.core.runtime;version="3.4.0",
org.h2;version="1.4.187",
org.h2.jdbc;version="1.4.187",
org.h2.jdbcx;version="1.4.187",
org.h2.util;version="1.4.187",
org.hibernate;version="4.3.9.Final",
org.hibernate.annotations;version="4.3.9.Final",
org.hibernate.ejb;version="4.3.9.Final",
org.hibernate.osgi;version="4.3.9.Final",
org.osgi.framework;version="1.8.0"
这是我的 persistence.xml
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
<class>hibernateh2osgi.User</class>
<class>hibernateh2osgi.Recipe</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<!-- Creates the Database in the Projectfolder -->
<property name="javax.persistence.jdbc.url" value="jdbc:h2:./CookieAppDatabase" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<!-- creates Table if nessesary, otherwise just update it -->
<property name="hibernate.hbm2ddl.auto" value="update" />
<!-- creates the Table and Drops it after Restart
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
-->
<property name="show_sql" value="true"/>
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
</properties>
</persistence-unit>
</persistence>
我试过这个,有没有指定要使用哪个持久性提供程序。
我看到了其他关于它的帖子,但我看不出我在那里做的错误。
这是来自激活器的代码。它只是启动 main 方法,因为我先用普通的 main 方法实现了它。
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
DataProviderImpl provider = new DataProviderImpl();
provider.main();
}
所以激活器启动这个:
public void main() {
DataProviderImpl cookie = new DataProviderImpl();
this.entityManager = EntityManagerUtil.getEntityManager();
User mo = new User();
}
哪个应该调用测试持久性xml
public class EntityManagerUtil {
private static final EntityManagerFactory entityManagerFactory;
static {
try {
entityManagerFactory = Persistence
.createEntityManagerFactory("test");
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static EntityManager getEntityManager() {
return entityManagerFactory.createEntityManager();
}
}
设法让它与下面的提示一起工作。但是最后我决定改变EntityManager的获取方式。我是这样实现的
Bundle thisBundle = FrameworkUtil.getBundle( EntityManagerUtil.class );
// Could get this by wiring up OsgiTestBundleActivator as well.
BundleContext context = thisBundle.getBundleContext();
ServiceReference serviceReference = context.getServiceReference(PersistenceProvider.class.getName());
PersistenceProvider persistenceProvider = (PersistenceProvider) context.getService(serviceReference);
entityManagerFactory = persistenceProvider.createEntityManagerFactory( "test", null);
entityManagerFactory.createEntityManager();
因此您正在使用静态 Persistence.createEntityManagerFactory 创建 EntityManagerFactory。虽然我在 OSGi 的 jpa 提供程序规范中读到这应该可以工作,但我从未尝试过这种方式,并且不确定您必须提供什么才能使其工作。
我通常使用 Aries JPA 作为 OSGi jpa 提供程序规范的实现。它有助于为您的持久性单元创建 EntityMangerFactory 并将其作为服务提供。看这个例子:http://www.liquid-reality.de/x/C4DK
我正在开发一个需要数据库的 OSGi 应用程序。 我选择为我的数据库使用 H2 和 Hibernate。
如何相信 EntityManager 找不到名称为 "test" 的持久性文件。我不相信 PersistenceProvider 不是 运行。当 运行 没有 OSGI 但作为 MavenProject 我没有得到这个错误。
这是控制台输出:
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
osgi> ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
Initial SessionFactory creation failed.javax.persistence.PersistenceException: No Persistence provider for EntityManager named test
!SESSION 2015-05-11 09:22:14.196 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.8.0_25
java.vendor=Oracle Corporation
BootLoader constants: OS=macosx, ARCH=x86_64, WS=cocoa, NL=de_DE
Command-line arguments: -dev file:/Users/christianverdion/Documents/workspace/HibernateH2OSGi/.metadata/.plugins/org.eclipse.pde.core/HibernateH2OSGi/dev.properties -os macosx -ws cocoa -arch x86_64 -consoleLog -console
!ENTRY hibernateh2osgi 4 0 2015-05-11 09:22:16.029
!MESSAGE FrameworkEvent ERROR
!STACK 0
org.osgi.framework.BundleException: Exception in hibernateh2osgi.Activator.start() of bundle hibernateh2osgi.
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:792)
at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:721)
at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:936)
at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:319)
at org.eclipse.osgi.container.Module.doStart(Module.java:571)
at org.eclipse.osgi.container.Module.start(Module.java:439)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1582)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1562)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1533)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1476)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
Caused by: java.lang.ExceptionInInitializerError
at hibernateh2osgi.EntityManagerUtil.<clinit>(EntityManagerUtil.java:16)
at hibernateh2osgi.DataProviderImpl.<init>(DataProviderImpl.java:15)
at hibernateh2osgi.Activator.start(Activator.java:32)
at org.eclipse.osgi.internal.framework.BundleContextImpl.run(BundleContextImpl.java:771)
at org.eclipse.osgi.internal.framework.BundleContextImpl.run(BundleContextImpl.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:764)
... 12 more
Caused by: javax.persistence.PersistenceException: No Persistence provider for EntityManager named test
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
at hibernateh2osgi.EntityManagerUtil.<clinit>(EntityManagerUtil.java:12)
... 18 more
Root exception:
java.lang.ExceptionInInitializerError
at hibernateh2osgi.EntityManagerUtil.<clinit>(EntityManagerUtil.java:16)
at hibernateh2osgi.DataProviderImpl.<init>(DataProviderImpl.java:15)
at hibernateh2osgi.Activator.start(Activator.java:32)
at org.eclipse.osgi.internal.framework.BundleContextImpl.run(BundleContextImpl.java:771)
at org.eclipse.osgi.internal.framework.BundleContextImpl.run(BundleContextImpl.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:764)
at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:721)
at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:936)
at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:319)
at org.eclipse.osgi.container.Module.doStart(Module.java:571)
at org.eclipse.osgi.container.Module.start(Module.java:439)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1582)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1562)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1533)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1476)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
Caused by: javax.persistence.PersistenceException: No Persistence provider for EntityManager named test
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
at hibernateh2osgi.EntityManagerUtil.<clinit>(EntityManagerUtil.java:12)
... 18 more
!ENTRY org.eclipse.osgi 4 0 2015-05-11 09:22:16.239
!MESSAGE Bundle hibernateh2osgi_1.0.0.qualifier [36] is not active.
我的 Manifest.MF 文件如下所示:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Hibernateh2osgi
Bundle-SymbolicName: hibernateh2osgi
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: hibernateh2osgi.Activator
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Meta-Persistence: META-INF/persistence.xml
Import-Package: javax.persistence;version="2.1.0",
org.eclipse.core.runtime;version="3.4.0",
org.h2;version="1.4.187",
org.h2.jdbc;version="1.4.187",
org.h2.jdbcx;version="1.4.187",
org.h2.util;version="1.4.187",
org.hibernate;version="4.3.9.Final",
org.hibernate.annotations;version="4.3.9.Final",
org.hibernate.ejb;version="4.3.9.Final",
org.hibernate.osgi;version="4.3.9.Final",
org.osgi.framework;version="1.8.0"
这是我的 persistence.xml
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
<class>hibernateh2osgi.User</class>
<class>hibernateh2osgi.Recipe</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<!-- Creates the Database in the Projectfolder -->
<property name="javax.persistence.jdbc.url" value="jdbc:h2:./CookieAppDatabase" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<!-- creates Table if nessesary, otherwise just update it -->
<property name="hibernate.hbm2ddl.auto" value="update" />
<!-- creates the Table and Drops it after Restart
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
-->
<property name="show_sql" value="true"/>
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
</properties>
</persistence-unit>
</persistence>
我试过这个,有没有指定要使用哪个持久性提供程序。
我看到了其他关于它的帖子,但我看不出我在那里做的错误。
这是来自激活器的代码。它只是启动 main 方法,因为我先用普通的 main 方法实现了它。
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
DataProviderImpl provider = new DataProviderImpl();
provider.main();
}
所以激活器启动这个:
public void main() {
DataProviderImpl cookie = new DataProviderImpl();
this.entityManager = EntityManagerUtil.getEntityManager();
User mo = new User();
}
哪个应该调用测试持久性xml
public class EntityManagerUtil {
private static final EntityManagerFactory entityManagerFactory;
static {
try {
entityManagerFactory = Persistence
.createEntityManagerFactory("test");
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static EntityManager getEntityManager() {
return entityManagerFactory.createEntityManager();
}
}
设法让它与下面的提示一起工作。但是最后我决定改变EntityManager的获取方式。我是这样实现的
Bundle thisBundle = FrameworkUtil.getBundle( EntityManagerUtil.class );
// Could get this by wiring up OsgiTestBundleActivator as well.
BundleContext context = thisBundle.getBundleContext();
ServiceReference serviceReference = context.getServiceReference(PersistenceProvider.class.getName());
PersistenceProvider persistenceProvider = (PersistenceProvider) context.getService(serviceReference);
entityManagerFactory = persistenceProvider.createEntityManagerFactory( "test", null);
entityManagerFactory.createEntityManager();
因此您正在使用静态 Persistence.createEntityManagerFactory 创建 EntityManagerFactory。虽然我在 OSGi 的 jpa 提供程序规范中读到这应该可以工作,但我从未尝试过这种方式,并且不确定您必须提供什么才能使其工作。
我通常使用 Aries JPA 作为 OSGi jpa 提供程序规范的实现。它有助于为您的持久性单元创建 EntityMangerFactory 并将其作为服务提供。看这个例子:http://www.liquid-reality.de/x/C4DK