Frage

Ich bin gerade auf eine von jemand anderem geschriebene Funktion gesprungen, die etwas ineffizient zu sein scheint, aber meine JPA-Kenntnisse sind nicht so gut, um eine tragbare Lösung zu finden, die nicht Hibernate-spezifisch ist.

Kurz gesagt führt die Dao-Methode, die innerhalb einer Schleife aufgerufen wird, um jede der neuen Entitäten einzufügen, einen „entityManager.merge(object);“ aus.

Ist in den JPA-Spezifikationen nicht eine Möglichkeit definiert, eine Liste von Entitäten an die Dao-Methode zu übergeben und eine Massen-/Batch-Einfügung durchzuführen, anstatt die Zusammenführung für jedes einzelne Objekt aufzurufen?

Da die Dao-Methode außerdem mit „@Transactional“ annotiert ist, frage ich mich, ob jeder einzelne Zusammenführungsaufruf innerhalb seiner eigenen Transaktion erfolgt ...was der Leistung nicht förderlich wäre.

Irgendeine Idee?

War es hilfreich?

Lösung

Nein, in Vanilla JPA gibt es keinen Batch-Einfügungsvorgang.

Ja, jede Einfügung erfolgt innerhalb einer eigenen Transaktion.Der @Transactional Attribut (ohne Qualifizierer) bedeutet eine Ausbreitungsebene von REQUIRED (Erstellen Sie eine Transaktion, falls diese noch nicht vorhanden ist.)Vorausgesetzt, Sie haben:

public class Dao {
  @Transactional
  public void insert(SomeEntity entity) {
    ...
  }
}

Du machst das:

public class Batch {
  private Dao dao;

  @Transactional
  public void insert(List<SomeEntity> entities) {
    for (SomeEntity entity : entities) {
      dao.insert(entity);
    }
  }

  public void setDao(Dao dao) {
    this.dao = dao;
  }
}

Auf diese Weise wird die gesamte Gruppe von Einfügungen in einer einzigen Transaktion verpackt.Wenn Sie über eine sehr große Anzahl von Einfügungen sprechen, möchten Sie diese möglicherweise in Gruppen von 1000, 10000 oder was auch immer aufteilen, da eine ausreichend große, nicht festgeschriebene Transaktion die Datenbank an Ressourcen belasten und möglicherweise allein aufgrund der Größe fehlschlagen kann.

Notiz: @Transactional ist eine Spring-Anmerkung.Sehen Transaktionsmanagement aus der Spring Reference.

Andere Tipps

Was Sie tun können, wenn Sie in einer listigen Stimmung sind, ist:

@Entity
public class SomeEntityBatch {

    @Id
    @GeneratedValue
    private int batchID;
    @OneToMany(cascade = {PERSIST, MERGE})
    private List<SomeEntity> entities;

    public SomeEntityBatch(List<SomeEntity> entities) {
        this.entities = entities;
    }

}

List<SomeEntity> entitiesToPersist;
em.persist(new SomeEntityBatch(entitiesToPersist));
// remove the SomeEntityBatch object later

Aufgrund der Kaskade, dass bewirkt, dass die Einheiten in einem einzigen Arbeitsgang eingefügt werden.

Ich bezweifle es ein praktischer Vorteil ist, dies zu tun, über einfach persistierenden einzelne Objekte in einer Schleife. Es wäre ein interessanter Blick auf die SQL sein, dass die JPA-Implementierung emittiert wird, und der Benchmark.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top