Spring数据:CrudRepository的保存方法和更新

时间:2016-08-11 10:31:07

标签: database hibernate spring-mvc spring-data spring-data-jpa

我想知道{save}中的CrudRepository方法是否在数据库中找到已更新的条目时进行更新:

@Repository
public interface ProjectDAO extends CrudRepository<Project, Integer> {}

@Service
public class ProjectServiceImpl {

@Autowired private ProjectDAO pDAO;

public void save(Project p) { pDAO.save(p); } }

因此,如果我在已经注册的条目上调用该方法,它会在找到更改的属性时更新它吗?

感谢。

5 个答案:

答案 0 :(得分:18)

  

我想知道CrudRepository中的{save}方法是否进行了更新   如果它已找到数据库中的条目

关于它的Spring文档并不精确:

  

保存给定的实体。使用返回的实例进行进一步操作   因为保存操作可能已经更改了实体实例   完全。

但是由于CrudRepository接口没有提出另一种具有更新实体的显式命名的方法,我们可能会认为是,因为CRUD应该执行所有CRUD操作(CREATE,READ,UPDATE, DELETE)。

此假设通过SimpleJpaRepository的实施得到确认 class是CrudRepository的默认实现,它表明这两种情况都由方法处理:

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

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

因此,如果我在已注册的条目上调用该方法,则会更新   它是否找到了更改的属性?

在这种情况下,它将执行合并操作。因此,所有字段都根据合并级联和只读选项的设置进行更新。

答案 1 :(得分:10)

查看CrudRepository接口的默认实现

 /*
     * (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);
        }
    }

保存方法管理两种情况:

- 如果人员Id为空(创建新实体),则保存将调用persist method =&gt;插入查询将被执行。

- 如果person id不为null,则save将调用merge:从entityManagerFactory获取现有实体(如果它不存在则从2级缓存获取,然后从数据库中获取)并比较分离具有托管的实体,最后通过调用更新查询将更改传播到数据库。

答案 2 :(得分:0)

我想知道如果CrudRepository中的{save}方法已找到数据库中的条目,它是否会进行更新:

答案是肯定的,如果找到条目,它会更新:

从Spring文档:这里https://docs.spring.io/spring-data/jpa/docs/1.5.0.RELEASE/reference/html/jpa.repositories.html

可以通过CrudRepository.save(...)-Method执行保存实体。它将使用基础JPA EntityManager持久化或合并给定实体。如果实体尚未持久化,Spring Data JPA将通过调用entityManager.persist(...)-Method来保存实体,否则将调用entityManager.merge(...)-Method。

答案 3 :(得分:0)

准确地说,如果 id为空,则save(obj)方法会将obj视为记录(因此会执行插入操作)并将对待obj如果 ID已填写,则为现有记录(因此将执行合并)。

为什么这很重要?

假设Project对象包含一个自动生成的id,还包含一个必须唯一的person_id。您创建一个Project对象并填写person_id但不填写id,然后尝试保存。 Hibernate将尝试插入此记录,因为id为空,但如果该人员已存在,则会出现重复的键异常。

如何处理
或者使用findByPersonId(id)检查obj是否已经在db中,如果找到则从中获取id,
或者只是尝试保存并捕获异常,在这种情况下,您知道它已经在数据库中,您需要在保存之前获取并设置ID。

答案 4 :(得分:0)

在我的情况下,我必须将id属性添加到Entity,并将注释@Id这样放。

templates

这种方式当你得到对象时,数据库中有实体的Id,并执行Update操作而不是Create。