Persistence.xml 和 OSGi (Equinox)
Posted
技术标签:
【中文标题】Persistence.xml 和 OSGi (Equinox)【英文标题】:Persistence.xml and OSGi (Equinox) 【发布时间】:2010-11-06 20:39:32 【问题描述】:我目前正在使用 OSGi 进行测试。我正在通过 Eclipse 运行它。我想将我的 DAO 层作为 OSGi 解决方案的一部分,但我的第一个绊脚石是这个错误:
Jun 29, 2009 6:12:37 PM org.hibernate.cfg.annotations.Version <clinit>
INFO: Hibernate Annotations 3.3.0.GA
Jun 29, 2009 6:12:37 PM org.hibernate.ejb.Version <clinit>
INFO: Hibernate EntityManager 3.3.0.GA
Jun 29, 2009 6:12:37 PM org.hibernate.ejb.Ejb3Configuration configure
INFO: Could not find any META-INF/persistence.xml file in the classpath
我尝试将persistence.xml 文件放在很多不同的地方,但无济于事。 关于我做错了什么有什么想法吗?
有没有办法手动加载persistence.xml?
激活器如下所示:
package com.activator;
public class PersistenceActivator implements BundleActivator
@Override
public void start(BundleContext arg0) throws Exception
EntityManagerFactory emf = Persistence
.createEntityManagerFactory("postgres");
EntityManager em = emf.createEntityManager();
SimpleDaoImpl dao = new SimpleDaoImpl();
dao.setEntityManager(em);
@Override
public void stop(BundleContext arg0) throws Exception
// TODO Auto-generated method stub
这是我的目录结构:
alt text http://www.freeimagehosting.net/uploads/7b7b7d2d30.jpg
这是我的 Manifest.MF
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Dao Plug-in
Bundle-SymbolicName: Dao
Bundle-Version: 1.0.0
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: org.osgi.framework;version="1.4.0"
Bundle-Activator: com.activator.PersistenceActivator
Export-Package: com.dao.service
Require-Bundle: HibernateBundle;bundle-version="1.0.0"
HibernateBundle 包含所有的 Hibernate 和 Persistence Jars。
这是我的 Persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence>
<!-- Sample persistence using PostgreSQL. See postgres.txt. -->
<persistence-unit name="postgres" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<!--
Comment out if schema exists & you don't want the tables dropped.
-->
<property name="hibernate.hbm2ddl.auto" value="create-drop" /> <!-- drop/create tables @startup, drop tables @shutdown -->
<!-- Database Connection Settings -->
<property name="hibernate.connection.autocommit">true</property>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.connection.username" value="postgres" />
<property name="hibernate.connection.password" value="postgres" />
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/test" />
<!-- Not sure about these... -->
<property name="hibernate.max_fetch_depth">16</property>
<property name="hibernate.jdbc.batch_size">1000</property>
<property name="hibernate.use_outer_join">true</property>
<property name="hibernate.default_batch_fetch_size">500</property>
<!-- Hibernate Query Language (HQL) parser. -->
<property name="hibernate.query.factory_class">
org.hibernate.hql.ast.ASTQueryTranslatorFactory</property>
<!-- Echo all executed SQL to stdout -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">false</property>
<!-- Use c3p0 for the JDBC connection pool -->
<property name="hibernate.c3p0.min_size">3</property>
<property name="hibernate.c3p0.max_size">100</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider" />
</properties>
</persistence-unit>
</persistence>
我在 Manifest 的 Classpath 中尝试过的事情都没有成功:
Bundle-ClassPath: ., META-INF/persistence.xml
Bundle-ClassPath: ., ../META-INF/persistence.xml
Bundle-ClassPath: ., /META-INF/persistence.xml
Bundle-ClassPath: ., ./META-INF/persistence.xml
Bundle-ClassPath: ., META-INF
Bundle-ClassPath: ., ../META-INF
Bundle-ClassPath: ., /META-INF
Bundle-ClassPath: ., ./META-INF
Bundle-ClassPath: ., C:\Workspaces\OSGiJPA\Dao\META-INF\persistence.xml
Bundle-ClassPath: ., C:\Workspaces\OSGiJPA\Dao\META-INF
【问题讨论】:
【参考方案1】:-
(只是一个建议):最好使用惰性加载器而不是在激活器中完成工作。例如,使用在 SimpleDaoImpl 构造函数中调用的单例。
将 META-INF/persistent.xml 移动到 src 文件夹 (src/META-INF/persistent.xml) 下,因为在 developer 下的 META-INF 文件夹不在类路径中,它仅在运行时模式下有效。
如果您使用的是 EclipseLink jpa OSGi,则您的 MANIFEST.MF 缺少 JPA-PersistenceUnits 条目。添加
JPA-PersistenceUnits:postgres
进入 MANIFEST.MF。
然后在您的启动配置中将 org.eclipse.persistence.jpa.osgi 的启动级别(对于 ecliselink 2.3.x 否则 org.eclipse.persistence.jpa 对于 2.1.x)设置为 2 和 javax.persistence 的启动级别到 1。祝你好运,实际上 2.3 在部署中存在问题,无法处理 bundleresource://xxxx URL :(, 2.1.2 工作得很好;)
【讨论】:
【参考方案2】:您需要设置属性(对于休眠它会有所不同):
javax.persistence.provider=org.apache.openjpa.persistence.PersistenceProviderImpl
通话:
Persistence.createEntityManagerFactory(entityManagerFactoryName, properties)
让它工作。
如前所述,您需要类加载器包装。您可以使用 https://issues.apache.org/jira/browse/OPENJPA-1783 中的 ClassloaderEntityManager 来执行此操作。
问候
【讨论】:
【参考方案3】:我遇到了同样的问题。
我认为 eclipse 链接是在 OSGi 环境中使用的最佳选择。没有问题,因为您基本上将使用 JPA 实现。当你需要迁移到 Hibernate 时,只需替换 persintece.xml 配置和一些库。
【讨论】:
教程在这里:wiki.eclipse.org/EclipseLink/Examples/OSGi/…【参考方案4】:您需要在类路径上有包含 META-INF 的目录。在每个目录中搜索 META-INF,如果找到,则搜索 persistence.xml。
如果您将“META-INF”放在类路径中,那么您需要在该目录中添加另一个 META-INF。
【讨论】:
【参考方案5】:使用 EclipseLink 并忘记 Hibernate 和其他实现,因为:
您将不得不过多地使用类加载器... Thread.currentThread().setContextClassLoader(...)
您会很想设置 bundle-classpath 属性并手动添加依赖项,而不是安装 jar 包。
您将收到 provider not found 错误,或者您可能无法找到 persistence.xml
经过多次尝试,上述所有努力可能都不起作用。
但是,使用 EclipseLink 就很容易了,该实现被设计为在 OSGI 环境中开箱即用,并且没有任何类加载问题。
【讨论】:
EclipseLink 确实是 OSGi 的更好选择(顺便说一下......它的 RI 用于 JPA 2)。根据 EL UserGuid,您应该使用以下内容加载 EMFactory: HashMap我使用的不是persistence.xml,而是类似的hibernate.cfg.xml:
src/main/resource/hibernate/hibernate.cfg.xml在我的 Activator 中,我通过包上下文获取文件: 这是一些示例代码,我如何执行它并引用该文件:>
私人无效initHibernate(BundleContext上下文) 尝试 最终 AnnotationConfiguration cfg = new AnnotationConfiguration(); cfg.configure(context.getBundle().getEntry("/src/main/resource/hibernate/hibernate.cfg.xml")); sessionFactory = cfg.buildSessionFactory(); 捕捉(异常 e) // TODO 自动生成的 catch 块如您所见,获取配置文件的行是:
context.getBundle().getEntry("/src/main/resource/hibernate/hibernate.cfg.xml")
如您所见,我的 hibernate.cfg.xml 不在 META-INF 文件夹中。它只是在/src/下的根文件夹中......
希望对您有所帮助。
克里斯托夫
【讨论】:
【参考方案7】:Meta-inf 目录不在类路径中。只需将其放在 src 目录下即可。如果您希望它位于单独的位置,则必须指定 Bundle-Classpath 以包含该目录。默认情况下,类路径是 '.'。
【讨论】:
我刚刚尝试将 META-INF 移动到 src 目录。但仍然无法正常工作。我也尝试过明确指向 Bundle-Classpath 中的 persistence.xml,但它不起作用。 @Grasper - 不要移动目录,将 persistence.xml 文件移动到源代码中,以便在编译时它位于您的类路径中。 所以我把persistence.xml放到src中,我有'.'在类路径上,它仍然不起作用。感谢您的帮助:-)【参考方案8】:尝试在清单中像这样使用 Bundle-ClassPath
Bundle-ClassPath: ., /location/of/persistence.xml
【讨论】:
不走运。我试过了:Bundle-ClassPath: ., META-INF/persistence.xml Bundle-ClassPath: ., ../META-INF/persistence.xml Bundle-ClassPath: ., /META-INF/persistence.xml Bundle-ClassPath: ., ./META-INF/persistence.xml Bundle-ClassPath: ., META-INF Bundle-ClassPath: ., ../META-INF Bundle-ClassPath: ., /META-INF Bundle-ClassPath: ., ./META-INF Bundle-ClassPath: ., C:\Workspaces\OSGiJPA\Dao\META-INF\persistence.xml Bundle-ClassPath: ., C :\Workspaces\OSGiJPA\Dao\META-INF 将 persistence.xml 移动到 jar 包的根目录?那应该把它捡起来以上是关于Persistence.xml 和 OSGi (Equinox)的主要内容,如果未能解决你的问题,请参考以下文章
如何为 JPA 和 Hibernate 创建一个 persistence.xml 文件?