2013-05-15 2 views
0

내 프로젝트에 계층화 된 아키텍처가 있습니다.Spring Hibernate : 일반적인 Dao 추가 원인 - org.hibernate.TransactionException : 중첩 된 트랜잭션이 지원되지 않음

public interface GenericDAO { 

    public <T> T getItemById(long id, Class<T> c); 

    public <T> int save(T... objectsToSave); 

    public <T> int saveOrUpdate(T... objectsToSave); 

    public <T> int delete(T... objectsToDelete); 
     . 
     . 
} 

이제 모든 내 다른 DAO의이 기본적인 방법을 사용하기 위해 개인 필드로이 일반적인 DAO를 사용합니다 : 예 :

중복을 방지하기 위해 내가 아주 기본적인 일반적인 DAO를 생성

@Repository 
public class UserDAOHibernateImpl implements UserDao { 

     @Autowired 
     private GenericDAO dao; 

     @Override 
     public int deleteUser(User u) { 
     return dao.delete(u); 

     } 

     . 
     . 
     . 
} 

내 서비스는 다음과 같습니다

@Service 
public class UserServiceHibernateImpl implements UserService { 

    @Autowired 
    private UserDao userDao; 


    @Transactional(readOnly = false) 
    public int deleteUser(User u) { 
     return userDao.deleteUser(u); 
    } 
     . 
     . 
     . 
} 

P

ApplicationContext ctx = new ClassPathXmlApplicationContext("root-context.xml"); 
    UserServiceHibernateImpl d = ctx.getBean("userServiceHibernateImpl", UserServiceHibernateImpl.class); 
    User u = d.getUserById(1); 

예외가 발생합니다 :

Exception in thread "main" org.hibernate.TransactionException: nested transactions not supported 
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:152) 
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1426) 
at src.com.plantaware.model.dao.impl.hibernate.GenericDAOHibernateImpl.getItemById(GenericDAOHibernateImpl.java:80) 
at src.com.plantaware.model.dao.impl.hibernate.GenericDAOHibernateImpl$$FastClassByCGLIB$$be31a192.invoke(<generated>) 
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191) 

이 문제를 해결합니다 내 서비스에서

@Autowired 
    private GenericDAO dao; 

제거를하지만 병 하나 하나에 중복 코드를 사용할 필요가 의미 roblem는 점이다 내 서비스 중, 그것은 일반적인 dao를 사용하여 완전히 빠진 것입니다.

이유가 무엇입니까? BTW

: 그없이 나는 " 'X'Y 형이어야합니다 이름 만 입력 [$ 프록시]의 사실이었다 콩"예외

감사를 받고 있어요 때문에 내가 CGLIB 프록시를 사용하고 있습니다 ..

답변

3

Hibernate 특정 트랜잭션 관리 (beginTransaction() 등)와 Spring 관련 선언적 트랜잭션 관리 (@Transactional)를 혼합합니다.

@Transactional을 사용하는 경우에는 DAO에서 beginTransaction() 등을 호출 할 필요가 없습니다. 필요한 트랜잭션 관리가 이미 Spring에 의해 제공되기 때문입니다. DAO에서 수동 트랜잭션 관리 코드를 제거하십시오.

은 참조 :

+0

오른쪽! 비록 내가 그것을 언급하지 않았지만, 나는 session.beginTransaction(); 내 DAO 내부. 그것을 제거하는 것은 나의 문제를 해결했다! 감사! – Urbanleg

0
TransactionException: nested transactions not supported 

은 거래를 시작할 때마다 내부에서 다른 거래를 시작할 수 없다는 것을 의미합니다. 먼저 끝내야합니다. 여기서, 내부 서비스 계층해야 DAO

@Repository 
public class UserDAOHibernateImpl implements UserDao { 

    @Autowired 
    private GenericDAO dao; // this is not acceptable. 

    @Override 
    public int deleteUser(User u) { 
    return dao.delete(u); 

    } 

    . 
    . 
    . 

}

모든 비즈니스 로직 내에서 DAO를 autowire하기 없습니다. Dao는 db 액세스만을 목표로합니다. 필요한 모든 콩을 서비스 안에 넣으십시오.

+0

그래서 내가 어떻게 UserDAOHibernateImpl 내부에서 GenericDAO를 호출 할 수 있어야한다? – Urbanleg