본문 바로가기
Spring Framework

Spring에서 multiple JPA persistence units 세팅

by BeGeek 2012. 10. 17.

Spring에서 다수의 JPA persistence units 을 세팅하려다 아래와 같이 에러가 나서 애먹었다;;

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [spring/applicationContext-jpa.xml]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: No single default persistence unit defined in {classpath:META-INF/persistence.xml}
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 

먼저 persistence.xml 에 아래와 같이 persistence-unit 을 teacher라는 이름으로 추가하고..

<persistence 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_1_0.xsd"
             version="1.0">

    <persistence-unit name="student"/>
    <persistence-unit name="teacher"/>
    
   
</persistence> 

아래와 같이 applicationContext-jpa.xml 라는 파일 내 entityManagerFactory bean  정의 부분의 property에

persistenceUnitName을 teacher라는 value 값으로 추가 했더니 나온 에러였다.

 <bean id="entityManagerFactory"
  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="persistenceUnitName" value="student" />
  <property name="persistenceUnitName" value="teacher" />
  
  <property name="jpaVendorAdapter">

   <!-- Use Hibernate as JPA engine -->
   <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
    p:database="${jpa.database}" p:showSql="${jpa.showSql}" />

   <!-- <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter"
    p:database="${jpa.database}" p:showSql="${jpa.showSql}"/> -->

  </property>
  <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
 </bean>

결론은 한개의 entityManagerFactory bean에 복수의 persistenceUnitName을 지정할 수 없다는것!

따라서 아래와 같이 entityMangerFactory2 라는 bean을 추가 생성하고

<!-- JPA EntityManagerFactory -->
 <bean id="entityManagerFactory"
  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="persistenceUnitName" value="student" />
  
  <property name="jpaVendorAdapter">

   <!-- Use Hibernate as JPA engine -->
   <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
    p:database="${jpa.database}" p:showSql="${jpa.showSql}" />

   <!-- <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter"
    p:database="${jpa.database}" p:showSql="${jpa.showSql}"/> -->

  </property>
  <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
 </bean>


 <bean id="entityManagerFactory2"
  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="persistenceUnitName" value="teacher" />
  
  <property name="jpaVendorAdapter">

   <!-- Use Hibernate as JPA engine -->
   <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
    p:database="${jpa.database}" p:showSql="${jpa.showSql}" />

   <!-- <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter"
    p:database="${jpa.database}" p:showSql="${jpa.showSql}"/> -->

  </property>
  <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
 </bean> 

각 jpaStudentDao.java 와 jpaTeacherDao.java 에 아래와 같이 (uniName =" ") 을 구분하여 지정하여 해결했다!

@Repository("studentDao")
public class JpaStudentDao implements StudentDao {
 
    @PersistenceContext(unitName ="student")
    private EntityManager entityManager;

    @Transactional
    public void store(Student student) {
        entityManager.merge(student);
    }
 

 @Repository("teacherDao")
public class jpaTeacherDao implements TeacherDao {
 
 @PersistenceContext(unitName ="teacher")
    private EntityManager entityManager;

    @Transactional
    public void store(Teacher teacher) {
        entityManager.merge(teacher);
    }

 

댓글