Si vous spécifiez explicitement l'id dans spring-data-jpa et faites
enregistrer '' '', sélectionnez-le comme indiqué dans le journal ci-dessous, puis insérez-le.
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 (?, ?)
C'est le comportement de jpa de sélectionner si l'id a déjà été persistant, puis de l'insérer. Cependant, dans certains traitements par lots, il peut être clair que l'identifiant n'existe pas en tant que spécification. Dans ce cas, select est juste inutile et je veux l'empêcher. Voici comment empêcher cette présélection.
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()
}
Ajoutez une propriété pour vérifier le SQL émis en interne.
src/main/resources/application.properties
spring.jpa.show-sql=true
Classe d'entité. `` Persistable '' '' sera décrit plus tard.
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);
}
}
Lorsque le code ci-dessus est exécuté, il passe au journal SQL suivant.
Hibernate: insert into sample (name, id) values (?, ?)
Le
save``` de spring-data-jpa passe essentiellement par le `` SimpleJpaRepository # save '' suivant, et son implémentation est la suivante.
SimpleJpaRepository
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
Par défaut, isNew
est `false```, donc il devient` `ʻem.merge```, résultant en une insertion sélective. Ce comportement peut être modifié en implémentant
Persistable '' dans la classe d'entité. Cette fois, je veux empêcher la présélection, c'est-à-dire laisser JPA la reconnaître comme une nouvelle entité, donc j'essaye de renvoyer isNew
à `` `true```.
Recommended Posts