Предохранитель JBoss + JPA/гибернация

У меня есть пакет OSGI в JBoss Fuse 6.2, который импортирует jar с сущностями и классами dao.
Jar содержит:
Spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Configures the Camel Context-->

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

    <context:component-scan base-package="com.company"/>

    <tx:annotation-driven transaction-manager="transactionManager" />

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
        <property name="dataSource" ref="dataSource" />
        <property name="jpaDialect" ref="jpaDialect" />
    </bean>

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

        <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
        <property name="persistenceUnitName" value="jpaData" />
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
        <property name="jpaDialect" ref="jpaDialect" />
    </bean>

    <bean id="jpaVendorAdapter"
          class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="database" value="POSTGRESQL" />
        <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" />
    </bean>

    <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />


    <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource"> 
        <property name="driverClass" value="org.postgresql.Driver" />  
        <property name="url" value="jdbc:postgresql://localhost:5432/MyDB" />
        <property name="username"  value="postgres" />       
        <property name="password"  value="123456" />        
    </bean> 
</beans>

постоянство.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
    xmlns="http://java.sun.com/xml/ns/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_1_0.xsd">


   <persistence-unit name="jpaData" transaction-type="RESOURCE_LOCAL" >
       <provider>org.hibernate.ejb.HibernatePersistence</provider>

       <class>com.company.model.entity.Entity</class>          

       <properties>
           <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
           <property name="hibernate.archive.autodetection" value="class"/>
           <property name="hibernate.show_sql" value="true"/>
           <property name="hibernate.format_sql" value="true"/>
           <property name="hbm2ddl.auto" value="update"/>
       </properties>
   </persistence-unit>
</persistence>

Дао класс

@Repository
@Transactional
public class JpaEntityDao implements EntityDao {

    @PersistenceContext(unitName="jpaData")
    private EntityManager em;

    //methods that use EntityManager
}

Класс сущности

@Entity
@Table(name="entity", schema="public")
public class Entity {
   //fields with setters and getters
}

Я хочу использовать JpaEntityDao в своем комплекте. Я импортировал spring.xml из jar в spring xml пакета

Когда я устанавливаю бандл в Karaf, появляется ошибка:

16:27:30,684 | ERROR | ExtenderThread-8 | ContextLoaderListener            | 174 - org.springframework.osgi.extender - 1.2.1 | Application context refresh failed (OsgiBundleXmlApplicationContext(bundle=myBundle, config=osgibundle:/META-INF/spring/*.xml))
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in URL [bundle://749.0:1/META-INF/spring/spring.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: jpaData] class or package not found
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1514)[167:org.apache.servicemix.bundles.spring-beans:3.2.12.RELEASE_1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)[167:org.apache.servicemix.bundles.spring-beans:3.2.12.RELEASE_1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)[167:org.apache.servicemix.bundles.spring-beans:3.2.12.RELEASE_1]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)[167:org.apache.servicemix.bundles.spring-beans:3.2.12.RELEASE_1]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)[167:org.apache.servicemix.bundles.spring-beans:3.2.12.RELEASE_1]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)[167:org.apache.servicemix.bundles.spring-beans:3.2.12.RELEASE_1]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)[167:org.apache.servicemix.bundles.spring-beans:3.2.12.RELEASE_1]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1119)[169:org.apache.servicemix.bundles.spring-context:3.2.12.RELEASE_1]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:924)[169:org.apache.servicemix.bundles.spring-context:3.2.12.RELEASE_1]
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:69)[173:org.springframework.osgi.core:1.2.1]
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:355)[173:org.springframework.osgi.core:1.2.1]
    at org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)[173:org.springframework.osgi.core:1.2.1]
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:320)[173:org.springframework.osgi.core:1.2.1]
    at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:132)[174:org.springframework.osgi.extender:1.2.1]
    at java.lang.Thread.run(Thread.java:745)[:1.8.0_65]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: jpaData] class or package not found
    at org.hibernate.ejb.Ejb3Configuration.addNamedAnnotatedClasses(Ejb3Configuration.java:1431)[668:org.hibernate.entitymanager:4.2.19.Final-redhat-1]
    at org.hibernate.ejb.Ejb3Configuration.addClassesToSessionFactory(Ejb3Configuration.java:1214)[668:org.hibernate.entitymanager:4.2.19.Final-redhat-1]
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1058)[668:org.hibernate.entitymanager:4.2.19.Final-redhat-1]
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:703)[668:org.hibernate.entitymanager:4.2.19.Final-redhat-1]
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:75)[668:org.hibernate.entitymanager:4.2.19.Final-redhat-1]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:290)[716:org.apache.servicemix.bundles.spring-orm:3.2.12.RELEASE_1]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)[716:org.apache.servicemix.bundles.spring-orm:3.2.12.RELEASE_1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1573)[167:org.apache.servicemix.bundles.spring-beans:3.2.12.RELEASE_1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1511)[167:org.apache.servicemix.bundles.spring-beans:3.2.12.RELEASE_1]
    ... 14 more
Caused by: java.lang.ClassNotFoundException: com.company.model.Entity not found by org.hibernate.entitymanager [668]
    at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1556)[org.apache.felix.framework-4.4.1.jar:]
    at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:77)[org.apache.felix.framework-4.4.1.jar:]
    at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1993)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)[:1.8.0_65]
    at java.lang.Class.forName0(Native Method)[:1.8.0_65]
    at java.lang.Class.forName(Class.java:348)[:1.8.0_65]
    at org.hibernate.internal.util.ReflectHelper.classForName(ReflectHelper.java:170)[670:org.hibernate.core:4.2.19.Final-redhat-1]
    at org.hibernate.ejb.Ejb3Configuration.classForName(Ejb3Configuration.java:1348)[668:org.hibernate.entitymanager:4.2.19.Final-redhat-1]
    at org.hibernate.ejb.Ejb3Configuration.addNamedAnnotatedClasses(Ejb3Configuration.java:1420)[668:org.hibernate.entitymanager:4.2.19.Final-redhat-1]
    ... 22 more

Похоже, что Karaf находит определение класса в файле persistence.xml, но не может загрузить класс Entity.
Приветствуются любые предложения.


person Montroz    schedule 27.10.2015    source источник
comment
Удалось ли вам решить эту проблему? Если да, то не могли бы вы поделиться подробностями. Я тоже столкнулся с подобной проблемой :(   -  person casper    schedule 13.12.2016
comment
см. мой комментарий ниже, это работает. Вы можете посмотреть примеры.   -  person Montroz    schedule 13.12.2016


Ответы (2)


Кажется, что spring - плохой выбор для osgi, и это было подтверждено там osgi">Использование Blueprint и Spring (не spring-dm) с OSGi.

Так что надо использовать Apache Aries. Вы можете найти рабочий пример jpa+fuse здесь https://github.com/pires/fabric8-persistence-hibernate
https://github.com/FuseByExample .

person Montroz    schedule 30.10.2015

Поскольку объект импортируется из другого jar и загружается пакетом через EntityManager, вам, вероятно, потребуется собрать jar как пакет и экспортировать пакеты, а затем импортировать пакеты с помощью `maven-bundle-plugin', например

Банка:

<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
            <Import-Package />
            <DynamicImport-Package>*</DynamicImport-Package>
            <Export-Package>com.company.model.*</Export-Package>
        </instructions>
    </configuration>
</plugin>

Пакет OSGi:

<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
            <Import-Package>com.company.model.entity</Import-Package>
            <DynamicImport-Package>*</DynamicImport-Package>
            <Export-Package />
        </instructions>
    </configuration>
</plugin>

Вы можете проверить импорт и экспорт пакетов, используя packages:imports, packages:exports. Было бы еще лучше создать функцию, определяющую пакеты, от которых она зависит.

person Tim    schedule 03.02.2016