title: Spring Data JPA - Multiple Persistence Units working as JUnit, but not in Tomcat
body: <p>I am nearly ready to fall back to my comfortable JDBC Template use for this one, but thought I'd see if the community has any insight. I added a 2nd set of JPA framework objects to my Spring-based application: new Entity Manager, Persistence Unit, etc. The exising Entity Manager uses ObjectDB for persistence and I want to use the slick Spring Data JPA API for a CRUD repository (Hibernate as an impl) but it's giving me trouble all along the way. I thought I had resolved everything locally b/c I had a JUnit that got past bean creation, but once I dropped those beans into an applicationContext I had a regression that I do not know how to fix</p>
  
  <p>JUnit and Application context XML snippet with company name removed from the com.xxx</p>
  
  <pre><code>&lt;context:annotation-config /&gt;
  &lt;context:component-scan base-package="com"/&gt;
  &lt;jpa:repositories base-package="com.dms.server.mode" entity-manager-factory-ref="emf"/&gt;
  &lt;!-- TxMgr #1 --&gt;
  &lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"&gt;
      &lt;property name="entityManagerFactory" ref="emf" /&gt;
  &lt;/bean&gt;
  &lt;!-- EMF #1 --&gt;
  &lt;bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource"&gt;
      &lt;property name="persistenceUnitName" value="hibernate-pu" /&gt;
      &lt;property name="persistenceXmlLocation" value="classpath:META-INF/persistence-hibernate.xml"/&gt;
      &lt;property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/&gt;
      &lt;property name="jpaVendorAdapter"&gt;
          &lt;bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /&gt;
      &lt;/property&gt;
      &lt;property name="jpaProperties"&gt;
          &lt;props&gt;
              &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.MySQL5InnoDBDialect&lt;/prop&gt;
              &lt;prop key="hibernate.show_sql"&gt;true&lt;/prop&gt;
          &lt;/props&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  
  &lt;bean id="sharedModeManager" class="com.dms.server.mode.DefaultSharedModeManager"/&gt;
  &lt;bean id="changeRecordCommandFactory" class="com.dms.server.ChangeRecordCommandFactory"/&gt;
  
  &lt;bean id="createModeCommand" class="com.dms.server.mode.CreateModeCommand"&gt;
      &lt;property name="apsConnection" ref="ApsConnection" /&gt;
  &lt;/bean&gt;
  
  &lt;!-- TxMgr #2 --&gt;
  &lt;bean id="EnvDMSTxManager" class="org.springframework.orm.jpa.JpaTransactionManager"&gt;
      &lt;property name="entityManagerFactory" ref="EnvDMSEntityManagerFactory"/&gt;
  &lt;/bean&gt;
  &lt;!-- EMF #2 --&gt;
  &lt;bean id="EnvDMSEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
      &lt;property name="persistenceUnitName" value="envService"/&gt;
      &lt;property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/&gt;
      &lt;property name="persistenceProviderClass" value="com.objectdb.jpa.Provider"/&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>persistence-hibernate.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;persistence version="2.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_2_0.xsd"&gt;
  &lt;persistence-unit name="hibernate-pu" transaction-type="RESOURCE_LOCAL"&gt;
      &lt;provider&gt;org.hibernate.ejb.HibernatePersistence&lt;/provider&gt;
      &lt;mapping-file&gt;META-INF/orm-none.xml&lt;/mapping-file&gt;
      &lt;class&gt;com.api.dms.SharedMode&lt;/class&gt;
      &lt;class&gt;com.api.dms.SharedModeAssignment&lt;/class&gt;
      &lt;exclude-unlisted-classes&gt;true&lt;/exclude-unlisted-classes&gt;
      &lt;properties&gt;
          &lt;property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /&gt;
          &lt;property name="hibernate.hbm2ddl.auto" value="validate" /&gt;
          &lt;property name="hibernate.show_sql" value="true" /&gt;
      &lt;/properties&gt;
  &lt;/persistence-unit&gt;
  </code></pre>
  
  <p></p>
  
  <p>persistence.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;persistence version="2.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_2_0.xsd"&gt;
  &lt;persistence-unit name="envService" transaction-type="RESOURCE_LOCAL"&gt;
      &lt;provider&gt;com.objectdb.jpa.Provider&lt;/provider&gt;
      &lt;mapping-file&gt;META-INF/orm-objectdb.xml&lt;/mapping-file&gt;
      &lt;class&gt;com.awareness.server.environment.SampleIndicationHistory&lt;/class&gt;
      &lt;exclude-unlisted-classes&gt;true&lt;/exclude-unlisted-classes&gt;
      &lt;properties&gt;
          &lt;property name="javax.persistence.jdbc.url" value="$temp/awp/envService.odb" /&gt;
          &lt;property name="javax.persistence.jdbc.user" value="admin" /&gt;
          &lt;property name="javax.persistence.jdbc.password" value="admin" /&gt;
      &lt;/properties&gt;
  &lt;/persistence-unit&gt;
  </code></pre>
  
  <p></p>
  
  <p>orm-none.xml (everything is picked up via annotations, but if I don't specify this file, the other orm file is picked up)</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0"&gt;
  &lt;/entity-mappings&gt;
  </code></pre>
  
  <p>orm-objectdb.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd" version="2.0"&gt;
  &lt;entity class="com.awareness.server.environment.SampleIndicationHistory" access="FIELD"&gt;
      &lt;table name="SAMPLE_IND_HISTORY"/&gt;
      &lt;attributes&gt;
          &lt;id name="deviceId"/&gt;
          &lt;basic name="tOldest"/&gt;
          &lt;basic name="tNewest"/&gt;
          &lt;element-collection name="timestamps"/&gt;
          &lt;element-collection name="indexes"/&gt;
      &lt;/attributes&gt;
  &lt;/entity&gt;
  </code></pre>
  
  <p></p>
  
  <p>Again, this all works fine and dandy in a JUnit</p>
  
  <pre><code>@RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration(locations={"/com/junit-context.xml"})
  // Functioning JUnit
  </code></pre>
  
  <p>But fails in Tomcat with</p>
  
  <pre><code>Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sharedModeManager': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sharedModeRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.api.dms.SharedMode
  at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:306)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
  at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
  at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:323)
  ... 33 more
  Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sharedModeRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.api.dms.SharedMode
  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:1454)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:249)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
  at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:442)
  at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:416)
  at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:550)
  at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)
  at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
  at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303)
  ... 41 more
  Caused by: java.lang.IllegalArgumentException: Not an managed type: class com.api.dms.SharedMode
  at org.hibernate.ejb.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:171)
  at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.&lt;init&gt;(JpaMetamodelEntityInformation.java:68)
  at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:65)
  at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:146)
  at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:84)
  at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:67)
  at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:150)
  at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:162)
  at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:44)
  at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)
  ... 51 more
  </code></pre>
  
  <p>Java Classes</p>
  
  <pre><code>@Repository
  @PersistenceContext(unitName="hibernate-pu")
  public interface SharedModeRepository extends CrudRepository&lt;SharedMode, SharedModeKey&gt; {
  Iterable&lt;SharedMode&gt; findByName(String name);
  Iterable&lt;SharedMode&gt; findByCurrent(boolean current);
  SharedMode findBySharedModeKeyIdAndCurrent(int id, boolean current);
  }
  
  @PersistenceContext(name="hibernate-pu")
  @Entity(name="shared_mode")
  @XmlRootElement(name="sharedMode")
  public class SharedMode implements Comparable&lt;SharedMode&gt;, ModeLike, Serializable {
      private static final long serialVersionUID = -3202319961514321359L;
      @EmbeddedId
      @XmlElement
      private SharedModeKey sharedModeKey = new SharedModeKey();
      @Column
      private String name;
      @Column
      private boolean current;
      ...
  }
  </code></pre>
  
  <p>It's hard to know what is done differently in the start-up to make things fail, I've been stepping through a lot of framework code trying to determine exactly what goes wrong.</p>