programing

저장() 전에 스프링 데이터 JPA가 SELECT를 수행하지 않도록 하려면 어떻게 해야 합니까?

lovejava 2023. 8. 12. 09:40

저장() 전에 스프링 데이터 JPA가 SELECT를 수행하지 않도록 하려면 어떻게 해야 합니까?

기존 데이터베이스에 대해 새 앱을 작성하고 있습니다.저는 Spring Data JPA를 사용하고 있으며, 단순히

MyRepository.save() 

내 새 엔터티에서, 사용

MyRepository extends CrudRepository<MyThing, String>

로그에서 최대 절전 모드가 삽입 전에 선택을 수행하고 있으며 인덱스를 사용하는 경우에도 시간이 오래 걸립니다.

여기서 이것을 검색해 봤는데, 주로 찾은 답은 특히 최대 절전 모드와 관련이 있습니다.저는 JPA가 상당히 생소하고 적어도 Spring Data의 맥락에서 사용할 때 JPA와 Hibernate가 상당히 밀접하게 연관되어 있는 것 같습니다.링크된 답변은 최대 절전 모드 지속()을 사용하거나 세션을 사용하는 것을 제안합니다. 아마도 엔티티 관리자에서 제공할 수 있습니다.세션이나 엔티티 관리자 또는 Hibernate API로 직접 아무것도 할 필요가 없었습니다.지금까지 저장소에 save()와 몇 개의 @Query를 사용하여 간단한 삽입을 완료했습니다.

다음은 Spring Data 저장소를 사용하여 사용 중인 Spring SimpleJpaRepository의 코드는 다음과 같습니다.

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

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

다음 작업을 수행합니다.

기본적으로 Spring Data JPA는 지정된 도면요소의 식별자 속성을 검사합니다.식별자 속성이 null이면 엔티티는 새 항목으로 간주되고, 그렇지 않으면 새 항목이 아닌 항목으로 간주됩니다.

Spring 데이터 설명서 링크

따라서 엔티티 중 하나에 Null이 아닌 ID 필드가 있는 경우 Spring은 Hibernate가 업데이트(이전에는 SELECT)하도록 합니다.

동일한 설명서에 나열된 두 가지 방법으로 이 동작을 재정의할 수 있습니다.간단한 방법은 엔터티가 지속 가능(Serialable) 대신 지속 가능(Persistable)을 구현하도록 하는 것이며, 이를 통해 "isNew" 방법을 구현할 수 있습니다.

고유한 ID 값을 제공하면 Spring Data는 DB에 중복 키가 있는지 확인해야 한다고 가정합니다(따라서 select+insert).

다음과 같은 ID 생성기를 사용하는 것이 좋습니다.

@Entity
public class MyThing {
    @Id
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "uuid2")
    private UUID id;
}

자신의 ID를 삽입해야 하고 select+insert를 방지하려면 Persistable 등을 구현합니다.

@Entity
public class MyThing implements Persistable<UUID> {

    @Id
    private UUID id;

    @Override
    public UUID getId() {
        return id;
    }

    //prevent Spring Data doing a select-before-insert - this particular entity is never updated
    @Override
    public boolean isNew() {
        return true;
    }
}

에서 사용자 지정 메서드를 생성했습니다.@Repository:

    public void persistAll(Iterable<MyThing> toPersist) {
        toPersist.forEach(thing -> entityManager.persist(thing));
    }

고유한 ID 값을 제공하면 Spring Data는 DB에 중복 키가 있는지 확인해야 한다고 가정합니다(따라서 select+insert).

한 가지 옵션은 별도의 자동 생성 ID 열을 기본 키로 사용하는 것이지만 이 옵션은 중복된 것 같습니다.이미 계신 은 이 ID를 /Natural ID로 만드는 더 쉽기 입니다.@ID별도의 ID 열 대신 열을 사용합니다.

그렇다면 어떻게 문제를 해결할 것인가요?

은 해책은다같습다니과를 사용하는 입니다.@javax.persistence.Version모든 테이블의 새 versionNumber 열에 있습니다. 및 에는 " " " " 를 사용합니다.@Version모든 엔터티 클래스의 열입니다.

엔티티 클래스에 다음과 같은 열을 추가합니다.

  @javax.persistence.Version
  @Column(name = "data_version")
  private Long dataVersion;

SQL 파일에 열 추가:

"data_version"          INTEGER DEFAULT 0

는 Spring 데이터를 하지 않는 을 알 수 있습니다.Select Insert.

언급URL : https://stackoverflow.com/questions/45635827/how-do-i-stop-spring-data-jpa-from-doing-a-select-before-a-save