Wir schreiben eine neue App für eine vorhandene Datenbank. Ich verwende Spring Data JPA und mache einfach eine
MyRepository.save()
auf meiner neuen Entität verwenden
MyRepository extends CrudRepository<MyThing, String>
In den Protokollen ist mir aufgefallen, dass der Ruhezustand vor dem Einfügen ein Select ausführt und dass diese Zeit sehr lange dauert, selbst wenn die Indizes verwendet werden.
Ich habe das hier gesucht und die Antworten, die ich gefunden habe beziehen sich normalerweise auf Hibernate. Ich bin ziemlich neu bei JPA und es scheint, als seien JPA und Hibernate ziemlich eng miteinander verbunden, zumindest wenn sie im Rahmen von Spring Data verwendet werden. Die verknüpften Antworten schlagen die Verwendung von Hibernate persist () oder irgendwie eine Sitzung vor, möglicherweise von einem entityManager? Ich hatte nichts mit Sessions oder entityManagers oder direkt mit einer Hibernate-API zu tun. Bisher habe ich einfache Einfügungen mit save () und ein paar @Query in meinen Repositories gemacht.
Hier ist der Code von Spring SimpleJpaRepository, das Sie mit Spring Data Repository verwenden:
@Transactional
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
Es tut Folgendes:
Standardmäßig prüft Spring Data JPA die Bezeichner-Eigenschaft der angegebenen Entität. Wenn die Bezeichner-Eigenschaft null ist, wird die Entität als neu angenommen, andernfalls als nicht neu.
Link zur Spring Data-Dokumentation
Wenn also eines Ihrer Entitäten ein ID-Feld hat, das nicht null ist, veranlasst Spring, dass Hibernate ein Update ausführt (und zuvor ein SELECT).
Sie können dieses Verhalten auf zwei Arten überschreiben, die in derselben Dokumentation aufgeführt sind. Eine einfache Möglichkeit besteht darin, dass Ihre Entity Persistable (anstelle von Serializable) implementiert, wodurch Sie die Methode "isNew" implementieren.
Wenn Sie Ihren eigenen ID-Wert angeben, geht Spring Data davon aus, dass Sie den DB auf einen doppelten Schlüssel überprüfen müssen (daher select + insert).
Besser ist es, einen ID-Generator zu verwenden:
@Entity
public class MyThing {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
private UUID id;
}
Wenn Sie wirklich Ihre eigene ID eingeben müssen und das Auswählen + Einfügen verhindern möchten, implementieren Sie Persistable, z.
@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;
}
}