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.
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);
}
}
Wenn der obige Code ausgeführt wird, ändert er sich in das folgende SQL-Protokoll.
Hibernate: insert into sample (name, id) values (?, ?)
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