2016-06-29 9 views
2

Wir haben eine Spring Boot/Data-JPA (1.3.3.RELEASE) Anwendung mit Hibernate-Implementierung, wo eine CSV-Datei gelesen und in eine Datenbanktabelle namens FIRE_CSV_UPLOAD eingefügt wird. Für Datensätze, die bereits vorhanden sind, aktualisieren wir sie nur. Wir rufen die Datensatz-ID ab, indem wir nach dem eindeutigen Schlüssel (einer Kombination aus drei Spalten) suchen. Dieser Ansatz ist jedoch für Tausende von Datensätzen in CSV-Dateien ineffizient.Kann eine Entität aktualisiert werden, anstatt mit feder-data-jpa eingefügt zu werden, wenn die Entitäts-ID nicht bekannt ist, ohne eine Abfrage auszugeben?

Meine Frage ist, wie Datensatz aktualisieren, ohne die Tabelle für eindeutigen Schlüssel abzufragen? Wenn ich keine ID abfrage, wird der Datensatz anstelle des Updates eingefügt.

Ich kenne eine Möglichkeit, alle Datensätze abzurufen und ihre eindeutigen Schlüssel und ID-Paare in einer Karte zu speichern. Alle anderen Vorschläge werden sehr geschätzt. Die Codes lauten wie folgt:

Hinweis: Sie sind der Kürze halber minimiert.

@Entity 
@Table(name = "FIRE_CSV_UPLOAD", 
     uniqueConstraints={@UniqueConstraint(columnNames = {"account_number" , "account_type", "bank_client_id"})}) 
public class FireCsv { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 

    @NotNull 
    @Column(name="account_number") 
    private String accountNumber; 

    @NotNull 
    @Column(name="account_type") 
    private String accountType; 

    @NotNull 
    @Column(name="bank_client_id") 
    private String bankClientIdNumber; 

    ... 
    other fields/getters/setters 
} 

-

public interface FireCsvRepository extends JpaRepository<FireCsv, Long> { 

    @Query("select u from FireCsv u where u.accountNumber = :accountNumber and u.accountType = :accountType and u.bankClientIdNumber = :bankClientIdNumber ") 
    FireCsv findRecord(@Param("accountNumber") String accountNumber, 
         @Param("accountType") String accountType, 
         @Param("bankClientIdNumber") String bankClientIdNumber); 
} 

-

@Service 
public class FireCsvServiceImpl implements FireCsvService { 

    other fields/methods 
    ... 
    @Override 
    @Transactional 
    public FireCsv save(final FireCsv fireCsv) { 

     FireCsv existingFireCsv = fireCsvRepository.findRecord(fireCsv.getAccountNumber(), fireCsv.getAccountType(), fireCsv.getBankClientIdNumber()); 

     // If record exist then mark as update, if not as insert 
     if (existingFireCsv != null) { 
      fireCsv.setId(existingFireCsv.getId()); 
      fireCsv.setRecordStatus(CSVUploadRecordStatus.CSV_UPDATE.getStatus()); 
     } 
     else { 
      fireCsv.setRecordStatus(CSVUploadRecordStatus.CSV_INSERT.getStatus()); 
     } 

     fireCsv.setRecordStatusDate(new java.sql.Timestamp(new Date().getTime())); 
     return fireCsvRepository.save(fireCsv); 
    } 
} 
+0

Möglicherweise können Sie UPSERT Hibernate Native SQL-Anweisung verwenden. –

+0

@KarthikPrasad danke. Ich mag diese Idee, aber unser Anliegen ist Portabilitätsproblem, wie z. Postgresql zu MySQL und umgekehrt, und ORM-Provider. Darüber hinaus gibt es 100 Plusfelder in der genannten Tabelle. –

+0

Ich glaube nicht, dass es viel Overhead gibt. Da sowohl MySQL als auch Postgress und Oracle UPSERT unterstützen, würden Sie im Falle einer Switching-Datenbank nur Ihre native Insert-Anweisung ändern, wie zum Beispiel Pojos usw. Bleibt es gleich, wie Sie Ihr System entwerfen möchten, Maintainability VS Performance. Obwohl in diesem Fall, wenn Sie Wartungsfreundlichkeit anstreben, Ihre Leistung könnte schlecht schlagen –

Antwort

0

Sie vor der Entscheidung zu lesen, um ein Update zu machen oder einzufügen, ich glaube nicht, dass es einen Weg gibt um ihn herum.

Um das zu beschleunigen, sollten Sie einen Index zu Ihrer Datenbank hinzufügen mit den drei Spalten "account_number", "account_type", "bank_client_id".

Alternativ können Sie versuchen, eine Composite-ID mit @IdClass zu verwenden, wie in tutorial-jpa-composite-primary-key Die PPV-Anbieter angezeigt sollte als den Index automatisch für sie erstellen.

+0

Wir schätzen den Vorschlag. Wir werden einen Index für die drei Spalten erstellen, und das Tutorial ist definitiv sehr informativ. –