Вставка данных JPA Spring вместо обновления

Привет, я новичок в Sprig Data JPA, и мне интересно, хотя я передаю идентификатор сущности, данные jda Spring вставляют вместо слияния. Я думал, когда я реализую интерфейс Persistable и реализую два метода:

public Long getId();
public Boolean isNew();

Он будет автоматически сливаться, а не сохраняться.

У меня есть класс объектов под названием User like:

@Entity
@Table(name = "T_USER")
public class User implements Serializable, Persistable<Long> {

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "USER_ID")
   private Long id;

   @Column(name = "CREATION_TIME", nullable = false)
   private Date creationTime;

   @Column(name = "FIRST_NAME", nullable = false)
   private String firstName;

   @Column(name = "LAST_NAME", nullable = false)
   private String lastName;

   @Column(name = "MODIFICATION_TIME", nullable = false)
   private Date modificationTime;

И еще один класс

@Entity
@Table(name = "T_USER_ROLE")
public class UserRole implements Serializable, Persistable<Long> {

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Long roleId;

   @Column(name = "ROLE_NAME")
   private String userRole;
}

У меня есть пользовательский репозиторий, называемый UserRepostory, расширяющий JpaReopistory. Я удаляю сохранение для слияния и сохраняю, поскольку я вижу, что реализация демонстрирует, что Spring Data Jpa использует выше двух методов для обновления или вставки.

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

Я пытался выяснить, но не понял. Может быть, вы, ребята, можете помочь.

Ответ 1

Я столкнулся с этой проблемой, попытался реализовать Persistable безрезультатно, а затем просмотрел источник Spring Data JPA. Я не обязательно вижу это в вашем примере кода, но у меня есть поле @Version в моей сущности. Если поле @Version Spring Data проверит это значение, чтобы определить, является ли объект новым или нет. Если поле @Version не является примитивным и равно null, объект считается новым.

Это очень долго меня бросало в мои тесты, потому что я не устанавливал поле версии в своем представлении, а только на сохраняемом объекте. Я также не вижу, что это описано в других полезных документах Spring Data (это еще одна проблема...).

Надеюсь, что кто-то поможет!

Ответ 2

По умолчанию Spring Data JPA проверяет свойство идентификатора данного объекта. Если свойство идентификатора - null, то сущность будет считаться новой, а не новой. Это Id-Property inspection Ссылка

Если вы используете Spring JPA с EntityManager, вызов .merge() обновит вашу сущность, а .persist() вставит.

@PersistenceContext
private EntityManager em;

@Override
@Transactional
public User save(User user) {

    if (user.getId() == null) {
        em.persist(user);
        return user;
    } else {
        return em.merge(user);
    }
}

Нет необходимости реализовывать интерфейс Persistable.