0

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

为了防止冗余,我创建了一个非常基本的通用 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] 类型”异常

谢谢..

4

2 回答 2

3

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

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

也可以看看:

于 2013-05-15T14:24:26.493 回答
0
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 放入您的服务中。

于 2013-05-15T14:23:53.543 回答