6

I'm trying to add one more database/schema/persistenceUnit in my project and I'm receiving the error:

No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 2

I google/api allot and could not found why spring is complaining about my configuration.

Here is part of my applicationContext.xml

  <bean id="entityManagerFactory" 
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

        <property name="dataSource" ref="dataSource" />
        <property name="persistenceUnitName" value="transactionManager" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="${show.hibernate.sql}" />
                <property name="generateDdl" value="false" />
                <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
            </bean>
        </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${database.driver}" />
        <property name="url" ...
        <property name="testOnBorrow" value="true" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

<bean id="entityManagerFactoryREST" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSourceREST" />
    <property name="persistenceUnitName" value="REST" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="${show.hibernate.sql}" />
            <property name="generateDdl" value="false" />
            <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
        </bean>
    </property>
</bean>

<bean id="dataSourceREST" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${database.driver}" />
    ...
    <property name="testOnBorrow" value="true" />
</bean>

<bean id="transactionManagerREST" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactoryREST" />
</bean>

<tx:annotation-driven transaction-manager="REST"/>
<tx:annotation-driven transaction-manager="transactionManager"/>


Some questions:

  • Do I need to have two tx:annotation-driven ?
  • Do I need to specify persistenceUnitName in the factory ?

I'm putting some notes of my digg in spring forum (LINK)

Well thats it... any help will be glad!

2
  • your first entity manager definition wasn't visible, and it was tricky ;) (fixed it) Commented Dec 9, 2009 at 20:21
  • give your @PersistenceContext usages Commented Dec 9, 2009 at 20:48

4 Answers 4

3

With Spring, you need to have only one EntityManagerFactory. What you are looking for is describe in the Spring documentation at the chapiter 13.5.1.4 : "Deals with multiple persitence units"

I copy/paste the text :

"13.5.1.4 Dealing with multiple persistence units

For applications that rely on multiple persistence units locations, stored in various JARS in the classpath, for example, Spring offers the PersistenceUnitManager to act as a central repository and to avoid the persistence units discovery process, which can be expensive. The default implementation allows multiple locations to be specified that are parsed and later retrieved through the persistence unit name. (By default, the classpath is searched for META-INF/persistence.xml files.)

<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
  <property name="persistenceXmlLocations">
    <list>
     <value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
     <value>classpath:/my/package/**/custom-persistence.xml</value>
     <value>classpath*:META-INF/persistence.xml</value>
    </list>
  </property>
  <property name="dataSources">
   <map>
    <entry key="localDataSource" value-ref="local-db"/>
    <entry key="remoteDataSource" value-ref="remote-db"/>
   </map>
  </property>
  <!-- if no datasource is specified, use this one -->
  <property name="defaultDataSource" ref="remoteDataSource"/>
</bean>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="persistenceUnitManager" ref="pum"/>
  <property name="persistenceUnitName" value="myCustomUnit"/>
</bean>

The default implementation allows customization of the PersistenceUnitInfo instances, before they are fed to the JPA provider, declaratively through its properties, which affect all hosted units, or programmatically, through the PersistenceUnitPostProcessor, which allows persistence unit selection. If no PersistenceUnitManager is specified, one is created and used internally by LocalContainerEntityManagerFactoryBean."

Sign up to request clarification or add additional context in comments.

Comments

1

This exceptions means that you are trying to autowire EntityManagerFactory by type. Do you have any @Autowired annotation in your code?

Aslo, when using @PersistenceContext, set the unit attribute correctly. And (I'm not sure if this is a proper thing to do) - try setting the name attribute to your respective factory name.

Also, check if you haven't copy-pasted incorrectly the REST transaction manager - now there is no such bean REST

5 Comments

No @Autowired annotations in my source, I always use:<br> @PersistenceContext private EntityManager em;
the <tx:annotation-driven transaction-manager="REST" /> - doesn't seem right
I understand that if I did not specify the unitName when using @PersistenceContext will use the default, take a look in this link: static.springsource.org/spring/docs/2.0.x/reference/… look the TIP
Which one is the default? There are two entity manager factories. The link you provided is about @Transactional, not @PersistenceContext
Yea sorry Bozho, actually what I mean to look in this link is about if I need to specify a name in tx:annotation-driven. Sorry my mistake!
0

Ensure all of your @PersistenceContext specify unitName. I haven't figured out how to tell Spring that a particular EMF or PersistenceUnit is the default. I thought specifying primary="true" on the default EMF would work but doesn't appear to

Comments

0

Do I need to specify persistenceUnitName in the factory ?

If you've got multiple persistence units, you do need to specify which ones the factories will use.

More to the heart of the matter, see SPR-3955. To summarize, versions prior to Spring 3.0M4 do not support multiple transaction managers with @Transactional. Nor do I believe it honors the "unitName" attribute for @PersistenceContext, so you can't specify that either.

For an example of how I worked around this by explicitly injecting EntityManagerFactorys and using AOP to re-enable @Transactional, see my sample app

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.