복붙노트

[SPRING] Equinox (OSGi) 및 JPA / Hibernate - 엔티티 찾기

SPRING

Equinox (OSGi) 및 JPA / Hibernate - 엔티티 찾기

OSGi (Equinox) 환경에서 Hibernate / Spring을 사용하려고합니다. Persistence.xml의 Entity 클래스를 명시 적으로 가리키면 멋지게 작동합니다.

    <class>com.es.t.eee.domain.StuffSource</class>
    <class>com.es.t.eee.domain.PostalAddress</class>

내가 원한 것은 Hibernate가 OSGi 환경 외부에서하는 것처럼 모든 Entity 클래스를 "발견"하는 것이다.

Hibernate는 @Entities에 대한 올바른 번들을 찾고있다 :

Searching mapped entities in jar/par: bundleresource://34/
WARN  27-07 15:30:24,235 (InputStreamZippedJarVisitor.java:doProcessElements:41):
Unable to find file (ignored): bundleresource://34/

작동해야하지만, @Entities에 대한 Bundle Jar를 찾을 때까지 예외가 발생하고 이유가 확실하지 않습니다. 나는 Hibernate가 뱉어내는 로그의 중요한 부분을 포함시켰다.

누구든지 내가 뭘 잘못하고 있는지 또는 여기있는 문제가 어떤 아이디어가 있습니까?

나는 다음을 사용하고있다 :

다음은 Hibernate가 Persistence.xml을 파싱하는 곳이다.

INFO  27-07 15:30:24,110 (Version.java:<clinit>:15):
Hibernate Annotations 3.4.0.GA
INFO  27-07 15:30:24,110 (Environment.java:<clinit>:543):
Hibernate 3.3.0.SP1
INFO  27-07 15:30:24,110 (Environment.java:<clinit>:576):
hibernate.properties not found
INFO  27-07 15:30:24,126 (Environment.java:buildBytecodeProvider:709):
Bytecode provider name : javassist
INFO  27-07 15:30:24,126 (Environment.java:<clinit>:627):
using JDK 1.4 java.sql.Timestamp handling
INFO  27-07 15:30:24,157 (Version.java:<clinit>:14):
Hibernate Commons Annotations 3.1.0.GA
INFO  27-07 15:30:24,157 (Version.java:<clinit>:16):
Hibernate EntityManager 3.4.0.GA
DEBUG 27-07 15:30:24,219 (Ejb3Configuration.java:configure:312):
Processing PersistenceUnitInfo [
    name: unit.postgresql
    persistence provider classname: null
    classloader: BundleDelegatingClassLoader for [DatabaseObjects (DatabaseObjects)]
    Temporary classloader: org.springframework.instrument.classloading.SimpleThrowawayClassLoader@11b50a1
    excludeUnlistedClasses: true
    JTA datasource: null
    Non JTA datasource: com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 1000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1012f6d821goxcok12zcw86|174f02c, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> org.postgresql.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1012f6d821goxcok12zcw86|174f02c, idleConnectionTestPeriod -> 0, initialPoolSize -> 5, jdbcUrl -> jdbc:postgresql://localhost:5432/test2, lastAcquisitionFailureDefaultUser -> null, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 100, maxStatements -> 100, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
    Transaction type: RESOURCE_LOCAL
    PU root URL: bundleresource://34/
    Jar files URLs []
    Managed classes names []
    Mapping files names []
    Properties [
        hibernate.default_batch_fetch_size: 500
        hibernate.cache.provider_class: net.sf.ehcache.hibernate.EhCacheProvider
        hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect
        hibernate.max_fetch_depth: 5
        hibernate.query.factory_class: org.hibernate.hql.ast.ASTQueryTranslatorFactory
        hibernate.format_sql: false
        hibernate.jdbc.batch_size: 1000
        hibernate.use_outer_join: true
        hibernate.archive.autodetection: class
        hibernate.show_sql: false
        hibernate.bytecode.provider: cglib]

다음은 엔티티를 찾으려고 할 때 오류가 발생하는 위치입니다.

DEBUG 27-07 15:30:24,235 (Ejb3Configuration.java:getDetectedArtifacts:562):
Detect class: true; detect hbm: false
DEBUG 27-07 15:30:24,235 (Ejb3Configuration.java:getDetectedArtifacts:562):
Detect class: true; detect hbm: false
DEBUG 27-07 15:30:24,235 (AbstractJarVisitor.java:unqualify:116):
Searching mapped entities in jar/par: bundleresource://34/
WARN  27-07 15:30:24,235 (InputStreamZippedJarVisitor.java:doProcessElements:41):
Unable to find file (ignored): bundleresource://34/
java.lang.NullPointerException: in is null
    at java.util.zip.ZipInputStream.<init>(Unknown Source)
    at java.util.jar.JarInputStream.<init>(Unknown Source)
    at java.util.jar.JarInputStream.<init>(Unknown Source)
    at org.hibernate.ejb.packaging.InputStreamZippedJarVisitor.doProcessElements(InputStreamZippedJarVisitor.java:37)
    at org.hibernate.ejb.packaging.AbstractJarVisitor.getMatchingEntries(AbstractJarVisitor.java:139)
    at org.hibernate.ejb.Ejb3Configuration.addScannedEntries(Ejb3Configuration.java:287)
    at org.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:614)
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:360)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:131)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:224)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:291)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
    at org.springframework.beans.factory.support.AbstractBeanFactory.isSingleton(AbstractBeanFactory.java:366)
    at org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean.afterPropertiesSet(OsgiServiceFactoryBean.java:235)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:423)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:288)
    at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:145)
    at java.lang.Thread.run(Unknown Source)

해결법

  1. ==============================

    1.이 블로그는 Spring의 동적 모듈로 어떻게 처리 할 수 ​​있는지 보여줍니다. 이 블로그를 기반으로, 애플리케이션 컨텍스트에서 DAO 및 Service Bean에 대한 Bean 정의를 작성한다. DAO는 hibernate sessionFactory 빈에 대한 참조를 가지고있다 :

    이 블로그는 Spring의 동적 모듈로 어떻게 처리 할 수 ​​있는지 보여줍니다. 이 블로그를 기반으로, 애플리케이션 컨텍스트에서 DAO 및 Service Bean에 대한 Bean 정의를 작성한다. DAO는 hibernate sessionFactory 빈에 대한 참조를 가지고있다 :

    <bean id="stuffDao" class="com.es.t.eee.domain.dao.StuffSourceDaoImpl">
      <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    <bean id="stuffService" 
      class="com.es.t.eee.domain.dao.StuffServiceImpl">
      <property name="stuffDao" ref="stuffDao"/>
    </bean>
    
    <bean id="stuffSource" 
      class="com.es.t.eee.domain.StuffSource" scope="prototype"/>
    

    StuffSourceDaoImpl은 StuffSource를 유지하기 위해 store () 메소드를 구현하고, StuffSource를 HibernateTemplate에 전달하여 실제로 지속성을 수행합니다.

    persistence.xml 파일을 정의하거나 모든 Entity를 지정하지 않으려면 AnnotationSessionFactoryBean과 와일드 카드를 사용하여 엔티티가 포함 된 패키지에 모든 유형을 포함시킬 수 있습니다 (대신 packagesToScan 속성을 설정하려고 할 수 있습니다. 이것을 시도하지 않았으므로 원래 문제로 돌아갈 수 있습니다.)

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
      <property name="hibernateProperties">
        <props>
          <!--etc-->
        </props>
      </property>
      <!-- set either one of these properties -->
      <property name="annotatedClasses">
        <list>
          <value>com.es.t.eee.domain.StuffSource</value>
          <value>com.es.t.eee.domain.PostalAddress</value>
        </list>
      </property>
      <property name="packagesToScan">
        <list>
          <value>com.es.t.eee.domain</value>
        </list>
      </property>
    </bean>
    

    이것을 사용하려면 BundleContext를 얻고 컨텍스트에서 서비스 및 Bean을 가져온 다음 정상적으로 수행하십시오.

    String serviceName = StuffService .class.getName();
    StuffService service = 
      (StuffService )context.getService(context.getServiceReference(serviceName));
    
    String stuffName = StuffSource.class.getName();
    StuffSource stuffSource = 
      (StuffSource) context.getService(context.getServiceReference(stuffName ));
    
    //do whatever with StuffSource
    ...
    
    service.store(stuffSource );
    

    관련된 OSGi Alliance 블로그를 살펴 보시기 바랍니다. OSGi Alliance 블로그에서 :

  2. ==============================

    2.이전 회신은 Hibernate와 OSGi의 문제에 관한 OSGi 블로그 항목을 언급하면서 유익한 읽을 거리입니다.

    이전 회신은 Hibernate와 OSGi의 문제에 관한 OSGi 블로그 항목을 언급하면서 유익한 읽을 거리입니다.

    나는 뒤로 물러나서 전통적인 Java 애플리케이션에 적용되는 가정과 OSGi 내부에서 더 이상 유효하지 않은 가정에 대해 생각해 보라고 제안한다.

    엔티티 클래스를 제공하는 번들보다 먼저 Hibernate 번들이 시작되면 어떻게 응용 프로그램이 작동할까요? 엔터티 클래스 검색이 작동하더라도 아무 것도 찾을 수 없습니다.

    전통적인 Java에서는 모든 클래스가 플랫 클래스 경로로 인해 시작될 때 사용할 수 있지만 OSGi 클래스는 기여한 번들이 시작되고 패키지를 가져 오는 경우에만 사용할 수 있습니다.

    OSGi는 의존성을 명시 적으로 연결해야한다. 번들 / 패키지를 가져 오지 않으면 해당 번들 / 패키지의 클래스를 볼 수 없습니다.

    엔티티 클래스를 명시 적으로 구성하는 것이 효과적이라고 말하기 때문에 다음 중 하나를 사용하여 종속성 연결을 수행한다고 가정합니다.

    리치 셀러의 제안은 효과가있다. (필자는 아직 테스트하지 않았다.) 엔티티 클래스가 포함 된 패키지를 가져와야한다. 그러나 이것에 대해서는 아무 것도 보이지 않으며 제안 된 솔루션은 명시 적으로 모든 것을 지정하는 것보다는 패키지 스캐닝을위한 옵션을 제공한다. 단일 엔티티 클래스.

    이제 옵션 1은 쉽고 옵션 2는 많은 작업을 필요로합니다. 그것은 모두 명시 적으로 패키지 / 클래스를 지정할 필요없이 Hibernate로부터 엔티티 클래스를 자동으로 추가 / 제거하는 것에 대한 당신의 요구 사항에 달려있다.

  3. from https://stackoverflow.com/questions/1190518/equinox-osgi-and-jpa-hibernate-finding-entities by cc-by-sa and MIT license