I'm building an OSGi application with Spring Data JPA, Gemini JPA, and Gemini DBAccess. This runs on Eclipse Virgo 3.6 connecting to a MySQL DB. EclipseLink is the JPA provider (abstracted by Gemini JPA).

I have a simple test bundle which contains a single DAO created with Spring Data JPA. This bundle uses an EntityManagerFactory provided by Gemini JPA, for a persistence unit contained in a different bundle. When I deploy this bundle to Virgo, I get the following error:

Code:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testDAO': Injection of persistence dependencies failed; nested exception is java.lang.IllegalArgumentException: JPA Metamodel must not be null!
	at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:342)
	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:585)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
	at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:60)
	at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:325)
	at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
	at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:290)
	at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:137)
	at org.eclipse.virgo.kernel.agent.dm.ContextPropagatingTaskExecutor$2.run(ContextPropagatingTaskExecutor.java:95)
	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: java.lang.IllegalArgumentException: JPA Metamodel must not be null!
	at org.springframework.util.Assert.notNull(Assert.java:112)
	at org.springframework.data.jpa.mapping.JpaMetamodelMappingContext.<init>(JpaMetamodelMappingContext.java:47)
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.setEntityManager(JpaRepositoryFactoryBean.java:50)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:159)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
	at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:339)
	... 18 common frames omitted
I can get this Spring Data JPA DAO working in a regular Java Spring app using a LocalContainerEntityManagerFactoryBean (i.e. no Virgo or OSGi involved). I can also create a working OSGi bundle which contains a manually created DAO (without Spring Data JPA involved). But, for some reason, I can't combine the two approaches and I've been tearing my hair out trying to understand what's going on.

Here's my bundle-context.xml:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:osgi="http://www.springframework.org/schema/osgi"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
		">

    <osgi:reference id="entityManagerFactory" interface="javax.persistence.EntityManagerFactory" filter="(osgi.unit.name=TestPU)" /> 
    
	<jpa:repositories base-package="foo.test.dao"/>
	
	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
       <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    
	<tx:annotation-driven transaction-manager="transactionManager" />
	
	<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"/>
	
	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

</beans>
Do I need to declare a "org.springframework.orm.jpa.support.PersistenceAn notationBeanPostProcessor" bean? I've tried with and without but it doesn't change the error I'm getting.

Here's my bundle's manifest, showing its dependencies:

Code:
Manifest-Version: 1.0
Bundle-Version: 1.0.0
Bundle-Name: Test DAO Bundle
Bundle-ManifestVersion: 2
Import-Package: 
 foo.test.model,
 javax.sql,
 org.aopalliance.aop;version="1.0.0"
Bundle-SymbolicName: com.payliquid.server.dao
Import-Bundle: 
 org.springframework.aop;version="[3.1.0.RELEASE,3.1.0.RELEASE]",
 org.springframework.aop;version="[3.1.0.RELEASE,3.1.0.RELEASE]",
 org.springframework.orm;version="[3.1.0.RELEASE,3.1.0.RELEASE]",
 org.springframework.transaction;version="[3.1.0.RELEASE,3.1.0.RELEASE]",
 org.springframework.context;version="[3.1.0.RELEASE,3.1.0.RELEASE]",
 org.springframework.beans;version="[3.1.0.RELEASE,3.1.0.RELEASE]",
 org.springframework.core;version="[3.1.0.RELEASE,3.1.0.RELEASE]",
 org.springframework.jdbc;version="[3.1.0.RELEASE,3.1.0.RELEASE]",
 org.springframework.data.core;version="[1.5.0.RELEASE,1.5.0.RELEASE]",
 org.springframework.data.jpa;version="[1.3.0.RELEASE,1.3.0.RELEASE]",
 javax.persistence;version="[2.0.4.v201112161009,2.0.4.v201112161009]"
Any thoughts or suggestions would be very gratefully received!