[JAVA] Spring Data JPA Save Select-Insert ist nur Insert

Phänomen

Wenn Sie die ID in spring-data-jpa explizit angeben und `` `save``` ausführen, wählen Sie sie wie im folgenden Protokoll gezeigt aus und fügen Sie sie dann ein.

Sample newEntity = new Sample(1L, "name");
repository.save(newEntity);
Hibernate: select sample0_.id as id1_0_0_, sample0_.name as name2_0_0_ from sample sample0_ where sample0_.id=?
Hibernate: insert into sample (name, id) values (?, ?)

Es ist das Verhalten von jpa, auszuwählen, ob die ID bereits beibehalten wurde, und sie dann einzufügen. Bei einigen Stapelverarbeitungen kann jedoch klar sein, dass die ID nicht als Spezifikation vorhanden ist. In diesem Fall ist select einfach nutzlos und ich möchte es verhindern. Im Folgenden wird beschrieben, wie Sie diese Vorauswahl verhindern können.

Quellcode

build.gradle


plugins {
  id 'org.springframework.boot' version '2.3.3.RELEASE'
  id 'io.spring.dependency-management' version '1.0.10.RELEASE'
  id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
  compileOnly {
    extendsFrom annotationProcessor
  }
}
repositories {
  mavenCentral()
}
dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
  compileOnly 'org.projectlombok:lombok'
  runtimeOnly 'com.h2database:h2'
  annotationProcessor 'org.projectlombok:lombok'
  testImplementation('org.springframework.boot:spring-boot-starter-test') {
    exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
  }
}
test {
  useJUnitPlatform()
}

Fügen Sie eine Eigenschaft hinzu, um das intern ausgegebene SQL zu überprüfen.

src/main/resources/application.properties


spring.jpa.show-sql=true

Entitätsklasse. `Persistable `wird später beschrieben.

import javax.persistence.Entity;
import javax.persistence.Id;

import org.springframework.data.domain.Persistable;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Sample implements Persistable<Long> {
	@Id
	Long id;

	String name;

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

	@Override
	public boolean isNew() {
		return true;
	}
}
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface SampleRepository extends JpaRepository<Sample, Long> {

}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.Transactional;

@EnableJpaRepositories
@SpringBootApplication
public class JpaSample implements CommandLineRunner {
	public static void main(String[] args) {
		SpringApplication.run(JpaSample.class, args);
	}

	@Autowired
	SampleRepository repository;
	
	@Transactional
	@Override
	public void run(String... args) throws Exception {
		Sample newEntity = new Sample(1L, "name");
		repository.save(newEntity);
	}

}

Ausführungsprotokoll

Wenn der obige Code ausgeführt wird, ändert er sich in das folgende SQL-Protokoll.

Hibernate: insert into sample (name, id) values (?, ?)

Kommentar

Das `save``` von spring-data-jpa durchläuft im Wesentlichen das folgende` SimpleJpaRepository # save``` und seine Implementierung ist wie folgt.

SimpleJpaRepository


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

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

Standardmäßig ist `isNew```` false, daher wird es zu `` `em.merge, was zu Select-Insert führt. Dieses Verhalten kann geändert werden, indem `Persistable``` in der Entitätsklasse implementiert wird. Dieses Mal möchte ich eine Vorauswahl verhindern, dh JPA als neue Entität erkennen lassen, also versuche ich, isNew``` auf `` true``` zurückzusetzen.

Recommended Posts

Spring Data JPA Save Select-Insert ist nur Insert
[spring] Verwenden wir Spring Data JPA
[So installieren Sie Spring Data Jpa]
Spring Data JPA SQL-Protokollausgabe
Existiert mit der Spezifikation in Spring Data JPA
Jackson kann hibernateLazyInitializer in Spring Data nicht JSON serialisieren JPA führt zu einem Fehler
Gegenseitige Bezugnahme auf Entity of Spring Data JPA und seine Anmerkungen
Sortieren nach Spring Data JPA (mit zusammengesetzter Schlüsselsortierung)
Erstellen eines gemeinsamen Repositorys mit Spring Data JPA
Spring Boot + Spring Data JPA Informationen zu mehreren Tabellenverknüpfungen
Ein Memorandum beim Versuch von Spring Data JPA mit STS
Ich habe versucht, mit Spring Data JPA zu beginnen
Bis zur Verwendung von Spring Data und JPA Part 2
Bis zur Verwendung von Spring Data und JPA Part 1
Machen Sie die where-Klauselvariable in Spring Data JPA