如果不发出查询就不知道实体 ID,是否可以使用 spring-data-jpa 更新而不是插入实体?

Can an entity be updated instead of being inserted using spring-data-jpa when entity ID is not known without issuing a query?

我们有一个使用 Hibernate 实现的 Spring Boot/Data-JPA (1.3.3.RELEASE) 应用程序,其中读取 CSV 文件并将其插入到名为 table 的数据库中30=]。对于已经存在的记录,我们只是更新它们。 我们通过查询唯一键(三列的组合)来检索记录 ID,但这种方法对于 CSV 文件中的数千条记录效率低下。

我的问题是如何在不查询 table 的唯一键的情况下更新记录?如果我不查询 ID,那么将插入记录而不是更新。

我知道一种方法是检索所有记录并将它们的唯一键和 ID 对存储在地图中。非常感谢任何其他建议。代码如下,

注意:为简洁起见,它们被最小化了。

@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);
    }
}

在决定进行更新或插入之前,您必须阅读,我认为没有办法解决它。

为了加快速度,您应该在数据库中添加索引 使用三列 "account_number"、"account_type"、"bank_client_id".

或者,您可以尝试使用 @IdClass 来使用复合 ID,如下所示 tutorial-jpa-composite-primary-key JPA 提供程序应该自动为其创建索引。