@Transactional注释 - Spring中的类级别和方法级别

时间:2014-06-07 06:06:09

标签: spring hibernate jpa jpa-2.1

请考虑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如何执行更新操作呢?

1 个答案:

答案 0 :(得分:0)

事务注释必须位于服务层,而不是DAO层。

每种DAO方法都应该执行一个操作,因此在此层中使用它是没有意义的。

如果需要执行多个操作,则将从服务层方法中调用各种DAO方法。