1

最近,我遇到了以下一段代码:

@Transactional
public MyEntity insert(MyEntity entity) {
    MyEntity merged = entityManager.merge(entity);
    return myEntityRepository.save(merged);
}

其中实体管理器定义如下:

@PersistenceContext private EntityManager entityManager;

和存储库是 Spring QueryDSL 存储库:

@Repository
public interface MyEntityRepository extends QueryDslRepository<MyEntity>{
}

entityManager.merge(entity)我的问题是,当我们使用myEntityRepository右边的实体持久化实体时,是否真的有必要调用?entityManager 是否正在做一些存储库不能做的事情?调用存储库还不够吗?

4

2 回答 2

2

对我来说,这看起来像是货物崇拜编程。如有必要,已经执行save()了合并(有时在不需要时):

/*
 * (non-Javadoc)
 * @see org.springframework.data.repository.CrudRepository#save(java.lang.Object)
 */
@Transactional
public <S extends T> S save(S entity) {

    if (entityInformation.isNew(entity)) {
        em.persist(entity);
        return entity;
    } else {
        return em.merge(entity);
    }
}
于 2018-07-30T11:22:14.633 回答
0

对我来说,这看起来是一个非常危险的代码,意图有点模糊,而且有些过度设计:

  1. 您是否 100% 保证在您的层和存储库之间共享相同的事务管理器?如果没有,你就有麻烦了。
  2. 你只是在做双重工作(@Jens 回答显示了它)。
  3. @Transactional这里只会让事情变得更糟(如果你有一些非标准的冲洗政策)。特别要注意,如果您从同一个类中调用方法,因为它通过代理工作,它将不起作用。
  4. 如果你真的打算insert()(新记录)你为什么需要merge()

我的投票是 - 就像save()@Jens 指出的那样使用。如果您真的需要insert()功能,那么您可能需要真正的事务以防止更新,在这种情况下,我会在存储库层上做一些自定义代码。希望你不需要它。

于 2018-07-30T11:48:45.420 回答