Nous écrivons une nouvelle application par rapport à une base de données existante. J'utilise Spring Data JPA et je fais simplement
MyRepository.save()
sur ma nouvelle entité, en utilisant
MyRepository extends CrudRepository<MyThing, String>
J'ai remarqué dans les journaux que l'hibernation effectue une sélection avant l'insertion et qu'elle prend beaucoup de temps, même lorsque vous utilisez les index.
J'ai cherché ceci, et les réponses que j'ai trouvées sont généralement liées à Hibernate en particulier. Je suis assez nouveau dans JPA et il semble que JPA et Hibernate soient assez étroitement liés, du moins lorsqu’on l’utilise dans le contexte de Spring Data. Les réponses liées suggèrent d'utiliser Hibernate persist () ou, d'une manière ou d'une autre, une session, éventuellement à partir d'un entityManager? Je n'ai rien eu à faire avec des sessions ou des entityManagers, ou directement avec une API Hibernate. Jusqu'à présent, j'ai effectué des insertions simples avec save () et un couple de @Query dans mes dépôts.
Voici le code de Spring SimpleJpaRepository que vous utilisez à l'aide du référentiel Spring Data:
@Transactional
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
Il fait ce qui suit:
Par défaut, Spring Data JPA inspecte la propriété d'identifiant de l'entité donnée. Si la propriété identifiant est null, l'entité sera considérée comme nouvelle, sinon non nouvelle.
Lien vers la documentation Spring Data
Et donc, si l’une de vos entités a un champ d’identification non nul, Spring fera effectuer à Hibernate une mise à jour (et donc un SELECT auparavant).
Vous pouvez remplacer ce comportement par les deux manières énumérées dans la même documentation. Un moyen simple consiste à rendre vos implémentations d'entité persistantes (au lieu de sérialisables), ce qui vous obligera à implémenter la méthode "isNew".
Si vous fournissez votre propre valeur d'identifiant, Spring Data supposera que vous devez rechercher une clé en double dans la base de données (d'où le paramètre select + insert).
La meilleure pratique consiste à utiliser un générateur d'identifiant, comme ceci:
@Entity
public class MyThing {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
private UUID id;
}
Si vous devez réellement insérer votre propre identifiant et que vous souhaitez empêcher la sélection + insertion, implémentez Persistable, par exemple.
@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;
}
}