Announcement Announcement Module
Collapse
No announcement yet.
Problem using multiple entity managers Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem using multiple entity managers

    Hi all. I'm working through a problem using two entity managers, with two distinct data sources and underlying schemas. I'm currently using Spring 3.1.2.RELEASE with Spring-Data 1.1.2.RELEASE.

    As you will be able to tell by contents of the application context, I have two separate modules... each in charge of their respective database objects and repository implementations. My base application uses each of these modules to communicate with their respective database schemas. Further detail:

    Application context:

    HTML Code:
    <tx:annotation-driven />
    			
    	<jdbc:embedded-database id="clientdb" />
    
    	<jpa:repositories base-package="....data.client" entity-manager-factory-ref="clientEmf" transaction-manager-ref="clientTxManager"/>
    
    	<bean id="clientEmf" name="clientEmf"
     		  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
       		<property name="dataSource" ref="clientdb" />
       		<property name="packagesToScan" value="....data.client.dbo" />
       		<property name="jpaVendorAdapter">
          		<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
          			<property name="database" value="HSQL" />
          		</bean>
       		</property>
       		<qualifier value="clientEmf"/>
    	</bean>
    	
    	<bean id="clientTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    	   <property name="entityManagerFactory" ref="clientEmf" />
    	</bean>
    
    	<bean id="clientDataContext" class="....ClientDataContext">
    		<constructor-arg>
    			<ref bean="clientdb" />
    		</constructor-arg>
    	</bean>
    
    
    	<jpa:repositories base-package="....data.admin" entity-manager-factory-ref="adminEmf" transaction-manager-ref="adminTxManager"/>
    	
    	<jdbc:embedded-database id="admindb" />
    
    	<bean id="adminEmf" name="adminEmf"
     		  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
       		<property name="dataSource" ref="admindb" />
       		<property name="packagesToScan" value="....data.admin.dbo" />
       		<property name="jpaVendorAdapter">
          		<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
          			<property name="database" value="HSQL" />
          		</bean>
       		</property>
       		<qualifier value="adminEmf"/>
    	</bean>
    	
    	<bean id="adminTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    	   <property name="entityManagerFactory" ref="adminEmf" />
    	</bean>
    
    	<bean id="adminDataContext" class="....data.admin.api.AdminDataContext">
    		<constructor-arg>
    			<ref bean="admindb" />
    		</constructor-arg>
    	</bean>
    I have two relevant interfaces:

    Code:
    public interface StuffRepositoryCustom {
    	
    	public List<Stuff> getStuff();
    
    }
    and

    Code:
    public interface StuffRepository extends JpaRepository<Stuff, Integer>, QueryDslPredicateExecutor<Stuff>, StuffRepositoryCustom {
    
    }

    and then my implementing class:

    Code:
    @Repository
    public class StuffRepositoryImpl implements StuffRepositoryCustom{
    	
    	EntityManager entityManager;
    	
    	@PersistenceContext(name="clientEmf")
    	public void setEntityManager(EntityManager em) {
    		entityManager = em;
    	}
    
            public List<Stuff> getStuff(){
                 ... some implementation
            }
    
    }

    My problem is that the wiring of the entity manager does not seem to be happening correctly. The root of the exception thrown is:

    Code:
    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 2
    So, my question is, how am I to delineate these two entity managers for use within the application? If I am interpreting the spring source documentation correctly here, entity-manager-factory-ref should have handled which entity manager gets directed to each of the contained subclasses. However, that does not seem to work as I expect.

    If I can provide any more information to help, please let me know! I've been working on this for a couple of days now to no avail. Thanks in advance!

  • #2
    As an additional note, I'm using Hibernate 4.1.7. I also found this error listed outside of the stack trace:

    Code:
    08:28:24.757 [main] WARN  o.h.e.i.EntityManagerFactoryRegistry - HHH000436: Entity manager factory name (default) is already registered.  If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name'
    I've been searching around for usages of that within my app context, but have come up short. Has anyone had to use this or run across the issue? Thanks


    Edit:

    I found how to use the above property, however, the same exception stack trace remains... minus the warning I had posted in this post. New clientEmf is defined as follows:

    Code:
    	<bean id="clientEmf" name="client"
     		  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
       		<property name="dataSource" ref="clientdb" />
       		<property name="packagesToScan" value="....data.client.dbo" />
       		<property name="jpaVendorAdapter">
          		<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
          			<property name="database" value="HSQL" />
          		</bean>
       		</property>
       		<property name="jpaProperties">
       		    <props>
       		         <prop key="hibernate.ejb.entitymanager_factory_name">clientEmf</prop>
       		    </props>
       		</property>
    	</bean>

    Still unsure of how to notify the framework to not register these two EntityManagers as default.
    Last edited by dpuwookie79; Dec 13th, 2012, 10:30 AM.

    Comment


    • #3
      I've stumbled upon another observation that has gotten this whole thing working it seems. I changed 3 things from my last post:

      1. The @Repository annotation was removed from each of the custom implementation classes.
      2. I added the property persistenceUnitName to each of my entityManagerFactory instances within my application context:
      HTML Code:
      <tx:annotation-driven />
      			
      	<jdbc:embedded-database id="clientdb" />
      
      	<jpa:repositories base-package="....data.client" entity-manager-factory-ref="clientEmf" transaction-manager-ref="clientTxManager"/>
      
      	<bean id="clientEmf"
       		  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
         		<property name="dataSource" ref="clientdb" />
         		<property name="packagesToScan" value="....data.client.dbo" />
         		<property name="jpaVendorAdapter">
            		<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            			<property name="database" value="HSQL" />
            		</bean>
         		</property>
         		<property name="persistenceUnitName" value="uniqueName1" />
      	</bean>
      	
      	<bean id="clientTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
      	   <property name="entityManagerFactory" ref="clientEmf" />
      	</bean>
      
      	<bean id="clientDataContext" class="....ClientDataContext">
      		<constructor-arg>
      			<ref bean="clientdb" />
      		</constructor-arg>
      	</bean>
      
      
      	<jpa:repositories base-package="....data.admin" entity-manager-factory-ref="adminEmf" transaction-manager-ref="adminTxManager"/>
      	
      	<jdbc:embedded-database id="admindb" />
      
      	<bean id="adminEmf" 
       		  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
         		<property name="dataSource" ref="admindb" />
         		<property name="packagesToScan" value="....data.admin.dbo" />
         		<property name="jpaVendorAdapter">
            		<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            			<property name="database" value="HSQL" />
            		</bean>
         		</property>
                      <property name="persistenceUnitName" value="uniqueName2" />
      	</bean>
      	
      	<bean id="adminTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
      	   <property name="entityManagerFactory" ref="adminEmf" />
      	</bean>
      
      	<bean id="adminDataContext" class="....data.admin.api.AdminDataContext">
      		<constructor-arg>
      			<ref bean="admindb" />
      		</constructor-arg>
      	</bean>

      3. I added the unitName property to my @PersistenceContext annotation above the EntityManager in each of my custom implementation classes:

      Code:
      public class StuffRepositoryImpl implements StuffRepositoryCustom{
      	@PersistenceContext(unitName="uniqueName2")
      	EntityManager entityManager;
      
              public List<Stuff> getStuff(){
                   ... some implementation
              }
      
      }
      For whatever reason it seems like the @Repository annotation was conflicting with something else going on in the application. Using the persistenceUnitNames along side the @Repository annotation produced the same error as in previous posts, but for some reason this combination seems to work. Can someone please comment on what may have been happening? Thanks!

      Comment

      Working...
      X