2013-05-15 49 views
0

我已经在我的项目分层架构。春休眠:通用的DAO另外原因 - org.hibernate.TransactionException:嵌套事务不支持

,以防止冗余我创建了一个非常基本的通用的DAO:

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作为私有字段,以便使用它的基本方法: 即:

@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 roblem是:

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; 
从我的服务将解决这一

,但是否意味着生病必须在每一个使用冗余代码我的服务,这完全没有使用通用道。

有什么想法为什么?

BTW:我使用CGLIB代理,因为如果没有我得到了“豆名为‘X’必须是Y型的,但为类型[$代理]实际上”异常

感谢..

回答

3

您正在将Spring特定的声明式事务管理(@Transactional)与Hibernate特定的手动事务管理(beginTransaction()等)混合使用。

如果您使用@Transactional,则不需要在DAO中调用beginTransaction()等,因为必需的事务管理已由Spring提供。从您的DAO中删除手动事务管理代码。

参见:

+0

你的权利!虽然我没有提到它,但我有session.beginTransaction();在我的道里面。删除它解决了我的问题!谢谢! – Urbanleg

0
TransactionException: nested transactions not supported 

表示无论何时开始一个事务,都不能在其中启动另一个事务。你首先需要完成它。在这里,不自动装配刀刀

@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的目标只有数据库访问。将所有必需的dao bean放入您的服务中。

+0

所以我应该怎么能够从里面UserDAOHibernateImpl打电话GenericDAO? – Urbanleg