java Persistence.xml 和 OSGi (Equinox)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1061091/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:59:11  来源:igfitidea点击:

Persistence.xml and OSGi (Equinox)

javajpajakarta-eeosgiequinox

提问by mainstringargs

I am currently testing out using OSGi. I am running this through Eclipse. I want to have my DAO layer as part of an OSGi solution, but my first stumbling block is this error:

我目前正在使用 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

I have tried putting the persistence.xml file in a lot of different places, to no avail. Any ideas on what I am doing wrong?

我曾尝试将persistence.xml 文件放在很多不同的地方,但无济于事。 关于我做错了什么的任何想法?

Is there a way to manually load the persistence.xml?

有没有办法手动加载persistence.xml?

The activatorlooks like this:

激活剂是这样的:

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

    }

}

Here is what my directory structure looks like:

这是我的目录结构的样子:

alt text http://www.freeimagehosting.net/uploads/7b7b7d2d30.jpg

替代文字 http://www.freeimagehosting.net/uploads/7b7b7d2d30.jpg

Here is my Manifest.MF

这是我的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"

HibernateBundlecontains all of the Hibernate and Persistence Jars.

HibernateBundle包含所有的 Hibernate 和 Persistence Jars。

Here is my Persistence.xml

这是我的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>

Things I have tried in the Manifest's Classpath with no luck:

我在 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/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: ., /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

Bundle-ClassPath: ., C:\Workspaces\OSGiJPA\Dao\META-INF

Bundle-ClassPath: ., C:\Workspaces\OSGiJPA\Dao\META-INF

采纳答案by Christoph

I am not using persistence.xml but hibernate.cfg.xml which is similar:

我没有使用persistence.xml,而是使用类似的hibernate.cfg.xml:

src/main/resource/hibernate/hibernate.cfg.xml

In my Activator I am getting the file via the bundle context: Here is some example code how I do it and also reference that file:>

在我的 Activator 中,我通过 bundle 上下文获取文件:这是一些示例代码,我如何做到这一点并引用该文件:>

private void initHibernate(BundleContext context) {
        try {
            final AnnotationConfiguration cfg = new AnnotationConfiguration();
            cfg.configure(context.getBundle().getEntry("/src/main/resource/hibernate/hibernate.cfg.xml"));
            sessionFactory = cfg.buildSessionFactory();

        } catch (Exception e) {
            // TODO Auto-generated catch block
        }
    }

As you can see line which gets the config file is:

如您所见,获取配置文件的行是:

context.getBundle().getEntry("/src/main/resource/hibernate/hibernate.cfg.xml")

As you can see my hibernate.cfg.xml is NOT inside the META-INF folder. It is just in the root folder under /src/......

如您所见,我的 hibernate.cfg.xml 不在 META-INF 文件夹中。它只是在/src/下的根文件夹中......

Hope that helps.

希望有帮助。

Christoph

克里斯托夫

回答by John Doe

Use EclipseLinkand forget about Hibernate and other implementations, because :

使用EclipseLink并忘记 Hibernate 和其他实现,因为:

  • You'll have to play with the classloader too much... Thread.currentThread().setContextClassLoader(...)

  • You'll be tempted to set the bundle-classpath attribute and add dependencies manually instead of installing jar bundles.

  • You'll get provider not founderrors or you might not be able to find persistence.xml

  • 您将不得不过多地使用类加载器... Thread.currentThread().setContextClassLoader(...)

  • 您会很想设置 bundle-classpath 属性并手动添加依赖项,而不是安装 jar 包。

  • 你会得到provider not found错误或者你可能无法找到persistence.xml

All the above efforts might not work after many attempts.

经过多次尝试,上述所有努力可能都不起作用。

However, with EclipseLink it's a no brainer, the implementation was designed to work out of the box in an OSGI environment and there aren't any class loading headaches.

但是,使用 EclipseLink 就很容易了,该实现旨在在 OSGI 环境中开箱即用,并且没有任何类加载问题。

回答by Nikolas Falco

  1. (only a suggestion): Better if you use a lazy loader instead do the job into the activator. For example use a singleton that is invoked into SimpleDaoImpl contructor.
  2. Move META-INF/persistent.xml under src folder (src/META-INF/persistent.xml) because under develop META-INF folder is not in classpath, it works only in runtime mode.
  3. If you are using EclipseLink jpa OSGi, your MANIFEST.MF missing of JPA-PersistenceUnits entry. Add

    JPA-PersistenceUnits: postgres

    into the MANIFEST.MF.

  4. Then in your launch configuration set the start level of org.eclipse.persistence.jpa.osgi (for ecliselink 2.3.x otherwise org.eclipse.persistence.jpa for 2.1.x) to 2 and start level of javax.persistence to 1.
  1. (只是一个建议):如果你使用惰性加载器而不是在激活器中完成工作会更好。例如,使用在 SimpleDaoImpl 构造函数中调用的单例。
  2. 将 META-INF/persistent.xml 移动到 src 文件夹(src/META-INF/persistent.xml)下,因为开发 META-INF 文件夹不在类路径中,它仅在运行时模式下工作。
  3. 如果您使用 EclipseLink jpa OSGi,则您的 MANIFEST.MF 缺少 JPA-PersistenceUnits 条目。添加

    JPA-PersistenceUnits:postgres

    进入MANIFEST.MF。

  4. 然后在您的启动配置中将 org.eclipse.persistence.jpa.osgi(对于 ecliselink 2.3.x 或 org.eclipse.persistence.jpa 对于 2.1.x)的启动级别设置为 2,并将 javax.persistence 的启动级别设置为 1。

GOOD LUCK, actually 2.3 has a problem in deployment, doesn't handle bundleresource://xxxx URLs :(, 2.1.2 works very well ;)

祝你好运,实际上 2.3 在部署中存在问题,无法处理 bundleresource://xxxx URL :(,2.1.2 运行良好;)

回答by Doug Milo

You need to have the directory that contains META-INF on the classpath. Each directory is searched for META-INF and if found, then persistence.xml is searched for.

您需要在类路径上拥有包含 META-INF 的目录。在每个目录中搜索 META-INF,如果找到,则搜索 persistence.xml。

If you put "META-INF" on the classpath, then you'd need another META-INF in that directory.

如果将“META-INF”放在类路径上,则该目录中需要另一个 META-INF。

回答by John John Pichler

I'm getting the same problem.

我遇到了同样的问题。

I think eclipse link is the best option to use in a OSGi Environment. And there are no problem because you will work basically with the JPA implementation. When you need to move to Hibernate, just replace persintece.xml config and some libs.

我认为 eclipse 链接是在 OSGi 环境中使用的最佳选择。并且没有问题,因为您将基本上使用 JPA 实现。当您需要迁移到 Hibernate 时,只需替换 persintece.xml 配置和一些库。

回答by Rafal Rusin

you need to set property (for hibernate it will be different):

您需要设置属性(对于休眠它会有所不同):

javax.persistence.provider=org.apache.openjpa.persistence.PersistenceProviderImpl

javax.persistence.provider=org.apache.openjpa.persistence.PersistenceProviderImpl

for call:

电话:

Persistence.createEntityManagerFactory(entityManagerFactoryName, properties)

Persistence.createEntityManagerFactory(entityManagerFactoryName, properties)

to make it work.

使其工作。

And as mentioned before, you need classloader wrapping. You can use ClassloaderEntityManager from https://issues.apache.org/jira/browse/OPENJPA-1783to do that.

如前所述,您需要类加载器包装。您可以使用https://issues.apache.org/jira/browse/OPENJPA-1783 中的ClassloaderEntityManager来做到这一点。

Regards

问候

回答by bwobbones

Try using Bundle-ClassPath like this in your manifest

尝试在清单中使用像这样的 Bundle-ClassPath

Bundle-ClassPath: ., /location/of/persistence.xml

Bundle-ClassPath: ., /location/of/persistence.xml

回答by Robin

The Meta-inf directory is not on the classpath. This should work by simply placing it under your srcdirctory. If you want it in a separate location, then you will have to specify the Bundle-Classpath to include that directory. By default the classpath is '.'.

Meta-inf 目录不在类路径上。这应该只需将它放在您的src目录下即可。如果您希望它位于单独的位置,则必须指定 Bundle-Classpath 以包含该目录。默认情况下,类路径是“.”。