【问题标题】:Spring Hibernate : Generic Dao addition causes - org.hibernate.TransactionException: nested transactions not supportedSpring Hibernate:Generic Dao 添加原因 - org.hibernate.TransactionException:不支持嵌套事务
【发布时间】:2013-05-10 03:57:04
【问题描述】:

我的项目中有一个分层架构。

为了防止冗余,我创建了一个非常基本的通用 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);
     }
         .
         .
         .
 }

问题是:

    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;

我的服务将解决这个问题,但这意味着我必须在我的每个服务上使用冗余代码,这完全没有使用通用 dao 的意义。

任何想法为什么?

顺便说一句:我正在使用 CGLIB 代理,因为没有它我会得到“名为 'X' 的 Bean 必须是 Y 类型,但实际上是 [$Proxy] 类型”异常

谢谢..

【问题讨论】:

    标签: spring hibernate dao transactional


    【解决方案1】:

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

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

    另请参阅:

    【讨论】:

    • 你的权利!虽然我没有提到它,但我有 session.beginTransaction();在我的道内。删除它解决了我的问题!谢谢!
    【解决方案2】:
    TransactionException: nested transactions not supported
    

    意味着无论何时你开始一个事务,你都不能在其中开始另一个事务。你首先需要完成它。在这里,不要在 dao 中自动装配 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 只针对 db 访问。将所有必要的 dao bean 放入您的服务中。

    【讨论】:

    • 那么我应该如何从 UserDAOHibernateImpl 内部调用 GenericDAO 呢?
    猜你喜欢
    • 1970-01-01
    • 2016-06-30
    • 2014-12-24
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多