JPA如何在id已存在时save报异常而不是update--希望save识别主键重复

问题

我希望Jpa在Save时,若主键已存在,直接报异常。
但Spring Jpa在Save时,进行了isNew的判断,若new则insert(persist),否则update(merge),我看到的JPA实现代码如下:

// JpaRepository.java
@Repository
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> implements JpaRepository<T, ID>, JpaSpecificationExecutor<T> {
    private final EntityManager em;

    @Transactional
    public <S extends T> S save(S entity) {

        if (entityInformation.isNew(entity)) {
            em.persist(entity);
            return entity;
        } else {
            return em.merge(entity);
        }
    }
    // ........
}

当前已有解决方案,希望确认一下是否有更优解。

当前的实现方案-自定义Query

@Modifying
@Query(nativeQuery = true,
       value = "INSERT INTO table_name(id, XXX, YYY) VALUES (:id, :XXX, :YYY);")
void insertXXXXX(@Param("id") String id,
                 @Param("XXX") String XXX,
                 @Param("YYY") String YYY);

此方案解决了问题,但感觉在维护上多了个SQL,如果有字段变化要同时维护数据库、DO、sql语句,希望有更好的解决方案

其他思路--EntityManager?

save method实际上调用了注入的EntityManager的persist或者merge,是否可以直接注入EntityManager调用persist?这样是否可行?

是否其他的更优的解决方案?

阅读 646
评论 更新于 2019-10-27
    2 个回答
    _TNT_
    • 2.8k

    实体类实现 Persistable
    isNew 方法一直返回 true 就行了
    但是先查询后插入应该更合理吧

    评论 赞赏 2019-11-01
      陨丶c
      • 3
      • 新人请关照

      你在service层暴露的接口把新增和修改2个操作区分出来不就行了?保证新增的接口传过来的实体id为空,不空就报错。

      评论 赞赏 2019-11-01
        撰写回答

        登录后参与交流、获取后续更新提醒