繁体   English   中英

在Spring数据存储库顶部使用EntityManager

[英]Using EntityManager on top of Spring Data Repositories

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

@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>{
}

我的问题是,当我们myEntityRepository使用myEntityRepository持久化实体时,是否真的有必要调用entityManager.merge(entity) 实体管理器在做某些事情,仓库无法做到吗? 调用存储库不够吗?

在我看来,这就像是对货物的崇拜。 必要时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);
    }
}

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

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

我的投票是-就像@Jens指出的那样使用save() 如果您确实需要insert()功能,那么您可能需要真正的交易并需要保护其免受更新,在这种情况下,我将在存储库层上执行一些自定义代码。 希望你不需要它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM