请考虑Spring中的以下案例(我正在使用Spring 4.0.0 GA和Hibernate 4.3.5 final。)
@Service
@Transactional(readOnly = true, propagation=Propagation.REQUIRED)
public final class ChangePasswordDAO implements ChangePasswordService
{
@PersistenceContext
private EntityManager entityManager;
public void setEntityManager(EntityManager entityManager)
{
this.entityManager = entityManager;
}
@Override
@SuppressWarnings("unchecked")
public String getOldPassword(UserTable userTable)
{
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<String>criteriaQuery=criteriaBuilder.createQuery(String.class);
Root<UserTable> root = criteriaQuery.from(entityManager.getMetamodel().entity(UserTable.class));
criteriaQuery.multiselect(root.get(UserTable_.password));
criteriaQuery.where(criteriaBuilder.equal(root, userTable));
List<String> list = entityManager.createQuery(criteriaQuery).getResultList();
return list!=null&&!list.isEmpty()?list.get(0):null;
}
@Override
@SuppressWarnings("unchecked")
public boolean changePassword(String password, UserTable userTable)
{
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaUpdate<UserTable> criteriaUpdate=criteriaBuilder.createCriteriaUpdate(UserTable.class);
Root<UserTable> root = criteriaUpdate.from(entityManager.getMetamodel().entity(UserTable.class));
criteriaUpdate.set(root.get(UserTable_.password), password);
criteriaUpdate.set(root.get(UserTable_.lastModified), DateTime.now(DateTimeZone.UTC));
criteriaUpdate.where(criteriaBuilder.equal(root, userTable));
return entityManager.createQuery(criteriaUpdate).executeUpdate()>0;
}
}
在这种情况下,我希望以下行
@Transactional(readOnly = false, propagation=Propagation.REQUIRED)
在changePassword()
方法之前,以便可以覆盖类级别@Transactional
注释。否则,类级别注释使用readOnly = true
也适用于此方法。因此,更新操作不应该发生,因为事务是只读的。
在这种情况下,Spring如何执行更新操作呢?
答案 0 :(得分:0)
事务注释必须位于服务层,而不是DAO层。
每种DAO方法都应该执行一个操作,因此在此层中使用它是没有意义的。
如果需要执行多个操作,则将从服务层方法中调用各种DAO方法。