代码之家  ›  专栏  ›  技术社区  ›  Smajl

在Spring数据存储库上使用EntityManager

  •  1
  • Smajl  · 技术社区  · 7 年前

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

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

    其中,实体经理定义如下:

    @PersistenceContext private EntityManager entityManager;
    

    存储库是SpringQueryDSL存储库:

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

    我的问题是,是否真的需要打电话 entityManager.merge(entity) 当我们使用 myEntityRepository 刚好在…之后?EntityManager是否在做存储库不能做的事情?调用存储库是否足够?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Jens Schauder    7 年前

    在我看来,这就像是货运邪教节目。这个 implementation of 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);
        }
    }
    
        2
  •  0
  •   Roman Nikitchenko    7 年前

    对于我来说,这看起来是一个非常危险的代码,有点模糊的意图,有些过于工程化:

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

    我的投票是-只是使用 save() 正如@jens指出的。如果你真的需要 插入() 功能,那么您可能需要真正的事务和更新保护,在这种情况下,我将在存储库层上做一些自定义代码。希望你不需要它。