Hibernate事务管理器-Java配置

Hibernate事务管理器-Java配置,java,spring,hibernate,spring-transactions,Java,Spring,Hibernate,Spring Transactions,我已经有一段时间在拼命工作了。我已创建以下数据访问对象: public interface GenericDAO<T, ID extends Serializable> { T findById(ID id); List<T> findAll(); T save(T entity); void update(T entity); void delete(T entity); } public class GenericHibernateDAO<

我已经有一段时间在拼命工作了。我已创建以下数据访问对象:

public interface GenericDAO<T, ID extends Serializable> {
  T findById(ID id);
  List<T> findAll();
  T save(T entity);
  void update(T entity);
  void delete(T entity);
}

public class GenericHibernateDAO<T, ID extends Serializable> implements GenericDAO<T, ID> {

  private final Class<T> persistentClass;
  private final SessionFactory sessionFactory;

  public GenericHibernateDAO(final SessionFactory sessionFactory) {
    this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    this.sessionFactory = sessionFactory;
  }

  protected Session getSession() {
    return sessionFactory.getCurrentSession();
  }

  public Class<T> getPersistentClass() {
    return persistentClass;
  }

  @Override
  public T findById(final ID id) {
    return (T) getSession().load(getPersistentClass(), id);
  }

  @Override @SuppressWarnings("unchecked")
  public List<T> findAll() {
    return findByCriteria();
  }

  protected List<T> findByCriteria(final Criterion... criterion) {
    final Criteria crit = getSession().createCriteria(getPersistentClass());
    for (final Criterion c : criterion) {
      crit.add(c);
    }
    return crit.list();
  }

  @Override
  public T save(final T entity) {
    getSession().saveOrUpdate(entity);
    return entity;
  }

  @Override
  public void delete(final T entity) {
    getSession().delete(entity);
  }

  @Override
  public void update(final T entity) {
    getSession().saveOrUpdate(entity);
  }
}

@Repository
public class StockHibernateDAO extends GenericHibernateDAO<Stock, String> implements StockDAO {

  @Inject
  public StockHibernateDAO(final SessionFactory sessionFactory) {
    super(sessionFactory);
  }
}
以下是TradingService:

@Service
public class TradingServiceImpl implements TradingService {    
  @Inject private StockDAO stockDAO;

  @Override @Transactional
  @CachePut(value = "stockCache", key = "#stock.name")
  public Stock addNewStock(final Stock stock) {
    stockDAO.save(stock);
    return stock;
  }

  @Override @Cacheable(value = "stockCache")
  public Stock getStock(final String stockName) {
    return stockDAO.findById(stockName);
  }

  @Override @CacheEvict(value = "stockCache", key = "#stock.name")
  public void removeStock(final Stock stock) {
    stockDAO.delete(stock);
  }

  @Override @CacheEvict(value = "stockCache", key = "#stock.name")
  public void updateStock(final Stock stock) {
    stockDAO.update(stock);
  }

  @Override
  public List<Stock> getAll() {
    return stockDAO.findAll();
  }
}
@服务
公共类TradingServiceImpl实现TradingService{
@注入私有StockDAO StockDAO;
@覆盖@Transactional
@CachePut(value=“stockCache”,key=“#stock.name”)
公开股票addNewStock(最终股票){
保存(库存);
退货;
}
@覆盖@Cacheable(value=“stockCache”)
公共股票getStock(最终字符串stockName){
返回stockDAO.findById(stockName);
}
@覆盖@cacheexecute(value=“stockCache”,key=“#stock.name”)
公开作废removeStock(最终库存){
删除(股票);
}
@覆盖@cacheexecute(value=“stockCache”,key=“#stock.name”)
公共作废更新库存(最终库存){
stockDAO.update(库存);
}
@凌驾
公共列表getAll(){
返回stockDAO.findAll();
}
}

只有在我将session.flush()添加到save方法中时,股票的保存才会完成。按照我的理解,在服务层方法中使用TransactionManager和@Transactional实际上应该会导致为我进行调用。此配置缺少什么?

因为您正在注入一个
会话

  @Bean
  public Session session() {
    return sessionFactory().openSession();
  }
Spring无法在其周围添加事务行为。让Spring打开会话,做它的事情

不要注入
会话
,而是注入
会话工厂
。在DAO中,为
SessionFactory
保留一个属性,并使用
SessionFactory.getCurrentSession()
获取会话

当Spring看到
@Transactional
时,它将获得
会话工厂
,调用
openSession()
,在其上开始一个事务,然后调用您的方法。当您的方法成功返回时,它将关闭该事务


您可能还应该
@Autowired
服务类中的dao。

如果我的dao被划分为@Transactional(即getCurrentSession()是否仅在事务中才有意义),这难道不起作用吗?目前,我想用事务标记我的服务层,而不是我的DAO层。不管谁拥有@Transactional,默认情况下,方法调用中的任何内容都将使用相同的会话和事务。然后,有些地方仍然不太正确,当我收到以下堆栈时:org.hibernate.hibernate异常:在org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:978)的org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)中找不到当前线程的会话在reference.dao.hibernate.generichbernatedao.getSession(generichbernatedao.java:25)中,只需将dao和服务实现注释为
@Repository
@Service
,让我们删除@injectstockdao并用
@Repository
注释该类或其实现。
  @Bean
  public Session session() {
    return sessionFactory().openSession();
  }