2012-07-30 19 views
9

Estoy tratando de implementar una solución usando una combinación de eclipselink (2.4.0) y spring-data-jpa (1.1.0.RELEASE). Sin embargo, cada vez que puedo implementar la solución (Tomcat 7), me sale el siguiente excepción:Eclipselink & Spring Data

Caused by: java.lang.IllegalArgumentException: No [ManagedType] was found for 
the key class [com.acme.domain.entities.User] in the Metamodel - please 
verify that the [Managed] class was referenced in persistence.xml using a 
specific <class>com.acme.domain.entities.User</class> property or a global 
<exclude-unlisted-classes>false</exclude-unlisted-classes> element. 

Parece que ocurra cuando el autowiring repositorio tiene lugar (ejemplos de código a continuación):

La clase de servicio

@Component 
public class UserDataService { 

    @Autowired 
    private UserRepository userRepository; 

    ... 
} 

Entidad clase

package com.acme.domain.entities; 

... 

@Entity 
@Table(name = "users") 
public class User implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "user_id") 
    private Integer id; 

    ... 

} 

persistence.xml

<persistence-unit name="default" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>  
    <class>com.acme.domain.entities.User</class> 

    ... 
</persistence-unit> 

¿Esto puede deberse a algún conflicto entre spring y eclipselink?

ACTUALIZACIÓN:

StackTrace ...

[#|2012-07-31 16:25:02,317|ERROR|pool-2-thread-40|org.springframework.web.context.ContextLoader|Context initialization failed|#] 
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDataService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.acme.data.repositories.UserRepository com.acme.data.services.UserDataService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: No [ManagedType] was found for the key class [com.acme.domain.entities.User] in the Metamodel - please verify that the [Managed] class was referenced in persistence.xml using a specific <class>com.acme.domain.entities.User</class> property or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element. 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:609) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:469) 
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:383) 
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283) 
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112) 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4779) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5273) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:897) 
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:873) 
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:615) 
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:958) 
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1599) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) 
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:680) 
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.acme.data.repositories.UserRepository com.acme.data.services.UserDataService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: No [ManagedType] was found for the key class [com.acme.domain.entities.User] in the Metamodel - please verify that the [Managed] class was referenced in persistence.xml using a specific <class>com.acme.domain.entities.User</class> property or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element. 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:512) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:92) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284) 
    ... 27 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: No [ManagedType] was found for the key class [com.acme.domain.entities.User] in the Metamodel - please verify that the [Managed] class was referenced in persistence.xml using a specific <class>com.acme.domain.entities.User</class> property or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element. 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:149) 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1442) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:305) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:876) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:818) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:484) 
    ... 29 more 
Caused by: java.lang.IllegalArgumentException: No [ManagedType] was found for the key class [com.acme.domain.entities.User] in the Metamodel - please verify that the [Managed] class was referenced in persistence.xml using a specific <class>com.acme.domain.entities.User</class> property or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element. 
    at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.entityEmbeddableManagedTypeNotFound(MetamodelImpl.java:174) 
    at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:489) 
    at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:58) 
    at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:65) 
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:149) 
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:87) 
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:70) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:137) 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:125) 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:41) 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142) 
    ... 37 more 
+0

puede incluir el seguimiento completo de la pila. ¿Es solo el metamodelo o no funcionan otras cosas? – James

+0

Agregué el stacktrace anterior, todo funciona bien siempre y cuando agregue mis propias implementaciones de repositorio, es decir, la parte del crucigrama eclipsel está bien. Tan pronto como agregue spring-data-jpa a la mezcla, lo anterior ocurre ... – NubieJ

+0

Teniendo exactamente este mismo problema en una aplicación independiente, ¿alguna actualización? – JBA

Respuesta

1

pude resolver mi problema, pero era otra configuración como la de arriba, acabo de añadir algunas cosas yo me encontré con hasta yo era capaz de resolverlo en mi sE-Medio Ambiente:

  • Bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=338837 afecta EclipseLink Versión 2.2.0 y por debajo de las versiones. Sucede principalmente en Local-Environment (RESOURCE_LOCAL). Un EclipseLink versión de actualización o la solución siguiente puede ayudar:
<exclude-unlisted-classes>false</exclude-unlisted-classes> 
  • Tener varios archivos persistence.xml en la ruta de clase (por ejemplo, sobre todo en los JAR partido 3o) que todos definen la misma persistencia de unidad nombre (arriba "predeterminado" puede ser muy común). Intente cambiar el nombre de su nombre de unidad de persistencia en este caso como primer paso

  • En caso de cambiar el nombre de la unidad de persistencia trabajado, pero al volver al valor anterior se reproduce el problema. o tarros viejos de su propio proyecto beeing incluyen para su acabado (por ejemplo refactorización/cambio de nombre en el nivel de proyecto o similares cambió la estructura así que por ejemplo una acumulación experto todavía podría tener viejos artefactos construir desde el repositorio)

Finaly cuando se trata de mi configuración (Spring-Standalone Application, no persistence.xml pero toneladas de configuraciones de Spring porque se usa un framework personalizado de la empresa) mostró que simplemente olvidé el anuncio d el paquete de entidad de framework-core personalizado cuando quería ejecutar una de sus implementaciones de servicio (implementación de Spring-Bean) en mi proyecto local en lugar de tener su implementación de servicio a partir de una dependencia de JAR. Así que asegúrese de que tiene todos los paquetes de entidad necesarios continuación, según su EntityManagerFactory:

<bean id="customEntityManagerFactory" parent="abstractEntityManagerFactory"> 
     <property name="dataSource" ref="dataSource"/> 


     <!-- Packages of EntityClasses --> 
     <property name="packagesToScan"> 
      <list merge="true"> 
       <value>ch.company.div1.foo.bar.model</value> 
       <value>ch.company.div1.foo.barnicle.model</value> 
       <value>ch.company.div2.we.help.model</value> 
      </list> 
     </property> 

     <property name="jpaProperties"> 
      <props merge="true"> 
       <prop key="eclipselink.target-database">org.eclipse.persistence.platform.database.SQLServerPlatform 
       </prop> 
       <prop key="javax.persistence.transactionType">RESOURCE_LOCAL</prop> 
      </props> 
     </property> 
    </bean> 

En mi caso me olvidó añadir el modelo packagege con los entitys utilizados de otra división (que escribe el núcleo marco personalizado) de nuestra compañía.

Buena suerte, que el error es una bestia:/

0

No está seguro de si tiene el mismo problema que tenía: tratar de crear 2 fábricas entidad diferente ... La excepción es la misma, por lo que tal vez esto ayude . Básicamente, esta excepción estaba ocurriendo cuando creaba una entidad en el EntityManagerFactory incorrecto.

Mi proyecto funcionaba bien con una única conexión de base de datos, pero cuando agregué un segundo, EclipseLink se confundió sobre dónde crear una instancia de mis entidades. Después de algunas depuraciones, mi conclusión fue eliminar la propiedad "packagesToScan" de mi raíz-contexto.xml y reemplazarla por "persistenceXmlLocation". En ese XML, hice una lista de todas las clases que tenía que ser escaneados y excluidos de todo lo demás con "< excluir-clases sin apuntar >"

Aquí está mi configuración XML completa que está trabajando actualmente:

raíz de contexto. xml

<bean id="dataSource1" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> 
    <property name="driverClassName" value="org.postgresql.Driver" /> 
    <property name="url" value="jdbc:postgresql://server1.example.com:5432/db1" /> 
    <property name="username" value="username" /> 
    <property name="password" value="password" /> 
    <property name="defaultAutoCommit" value="false" /> 
    <property name="initialSize" value="5" /> 
    <property name="maxIdle" value="5" /> 
    <property name="validationQuery" value="SELECT 1" /> 
    <property name="timeBetweenEvictionRunsMillis" value="600000" /> 
    <property name="poolPreparedStatements" value="true" /> 
    <property name="maxOpenPreparedStatements" value="10" /> 
</bean> 

<bean id="dataSource2" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> 
    <property name="driverClassName" value="org.postgresql.Driver" /> 
    <property name="url" value="jdbc:postgresql://server2.example.com:5432/db2" /> 
    <property name="username" value="user" /> 
    <property name="password" value="password" /> 
    <property name="defaultAutoCommit" value="false" /> 
    <property name="initialSize" value="5" /> 
    <property name="maxIdle" value="5" /> 
    <property name="validationQuery" value="SELECT 1" /> 
    <property name="timeBetweenEvictionRunsMillis" value="600000" /> 
    <property name="poolPreparedStatements" value="true" /> 
    <property name="maxOpenPreparedStatements" value="10" /> 
</bean> 


<bean id="emf1" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource1" /> 
    <property name="persistenceXmlLocation" value="classpath:META-INF/persistence1.xml" /> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"> 
      <property name="showSql" value="false" /> 
     </bean> 
    </property> 
    <property name="jpaPropertyMap"> 
     <map> 
      <entry key="eclipselink.weaving" value="false" /> 
      <entry key="eclipselink.logging.level" value="WARNING" /> 
      <entry key="eclipselink.logging.timestamp" value="false" /> 
      <entry key="eclipselink.logging.session" value="false" /> 
      <entry key="eclipselink.logging.thread" value="false" /> 
     </map> 
    </property> 
    <property name="loadTimeWeaver"> 
     <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /> 
    </property> 
</bean> 

<bean id="emf2" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource2" /> 
    <property name="persistenceXmlLocation" value="classpath:META-INF/persistence2.xml" /> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"> 
      <property name="showSql" value="false" /> 
     </bean> 
    </property> 
    <property name="jpaPropertyMap"> 
     <map> 
      <entry key="eclipselink.weaving" value="false" /> 
      <entry key="eclipselink.logging.level" value="WARNING" /> 
      <entry key="eclipselink.logging.timestamp" value="false" /> 
      <entry key="eclipselink.logging.session" value="false" /> 
      <entry key="eclipselink.logging.thread" value="false" /> 
     </map> 
    </property> 
    <property name="loadTimeWeaver"> 
     <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /> 
    </property> 
</bean> 

<bean name="transaction1" class="org.springframework.orm.jpa.JpaTransactionManager" p:entity-manager-factory-ref="emf1" /> 
<bean name="transaction2" class="org.springframework.orm.jpa.JpaTransactionManager" p:entity-manager-factory-ref="emf2" /> 

<jpa:repositories base-package="org.myproject.repository1" transaction-manager-ref="transaction1" entity-manager-factory-ref="emf1" /> 
<jpa:repositories base-package="org.myproject.repository2" transaction-manager-ref="transaction2" entity-manager-factory-ref="emf2" /> 

<tx:annotation-driven /> 

persistence1.xml

<persistence-unit name="persistence1" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
    <class>org.myproject.repository1.Repo1</class> 
    <class>org.myproject.repository1.Repo2</class> 
    <exclude-unlisted-classes>true</exclude-unlisted-classes> 
</persistence-unit> 

persistence2.xml

<persistence-unit name="persistence2" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
    <class>org.myproject.repository2.Repo1</class> 
    <class>org.myproject.repository2.Repo2</class> 
    <exclude-unlisted-classes>true</exclude-unlisted-classes> 
</persistence-unit> 

Por lo tanto, esto funciona para mí ...

Al parecer, especificando cada lugar "persistence.xml" impide que las clases que son para otra EntityManagerFactory a ser instanciadas en el primer "fem". De hecho, esto parece un error https://bugs.eclipse.org/bugs/show_bug.cgi?id=338837. Todo lo que pude deducir de mi depuración es que sin la "persistenceXmlLocation" TODAS las clases que se encuentran con "packageScan" se crearon en la primera "fem" creada, la segunda "fem" se ignoró por completo.

Espero que esto ayude. ¡Buena suerte!

0

Agregue el paquete (com.acme.domain.entities) con entidades al packagesToScan.

0

Conjunto del PersistenceUnitName, en lugar de la persistenceXmlLocation

Sin persistence.xml necesario.

factory.setPersistenceUnitName("dummy1"); 
factory.setPersistenceUnitName("dummy2"); 
Cuestiones relacionadas