簡體   English   中英

Spring-data-jpa:批量插入不起作用

[英]Spring-data-jpa: batch inserts are not working

我使用本文為我的一個實體使用 spring-data-jpa 實現批量插入。 我正在使用 MS SQL 數據庫。

我將主鍵生成策略從GenerationType.IDENTITY更改為GenerationType.SEQUENCE

@Entity
@Table(name = "Answers")
public class AnswerDMO implements java.io.Serializable {
    private static final long serialVersionUID = 1L;
    private long id;
    
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "answer_new_generator")
    @SequenceGenerator(name = "answer_new_generator", sequenceName = "answer_new_sequence", allocationSize = 15)
    @Column(name = "Id", unique = true, nullable = false)
    public long getId() {
        return this.id;
    }
    public void setId(long id) {
        this.id = id;
    }

服務方法通過調用<S extends T> List<S> save(Iterable<S> entities);答案實體列表。

@Transactional
public List<AnswersDMO> saveAnswers () {
       /* other logic..... */
       if(!CollectionUtils.isEmpty(answersToSave)) {
            supplementalAnswerNewDAO.save(answersToSave);
        }
}

為了告訴 Hibernate 在插入時使用批處理並檢查它是否實際工作,我設置了以下 JPA 屬性:

<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.hibernate.jdbc.batch_size">5</prop>
<prop key="hibernate.order_inserts">true</prop>

但是,在插入 11 個實體后,JDBC 批次計數為 0: 在此處輸入圖像描述

(Log4j2-TF-1-AsyncLogger[AsyncContext@44f54c5e]-1)     0 nanoseconds spent releasing 0 JDBC connections;
(Log4j2-TF-1-AsyncLogger[AsyncContext@44f54c5e]-1)     65217828 nanoseconds spent preparing 6 JDBC statements;
(Log4j2-TF-1-AsyncLogger[AsyncContext@44f54c5e]-1)     727057697 nanoseconds spent executing 6 JDBC statements;
(Log4j2-TF-1-AsyncLogger[AsyncContext@44f54c5e]-1)     0 nanoseconds spent executing 0 JDBC batches;

Hibernate 查詢:

08:02:35,739 INFO  [stdout] (default task-1) Hibernate: 
08:02:35,740 INFO  [stdout] (default task-1)     select
08:02:35,742 INFO  [stdout] (default task-1)         next value for supplemental_answer_new_sequence

08:02:57,941 INFO  [stdout] (default task-1) Hibernate: 
08:02:57,941 INFO  [stdout] (default task-1)          insert 
08:02:57,941 INFO  [stdout] (default task-1)         into
08:02:57,941 INFO  [stdout] (default task-1)             my_schema.dbo.Answers
08:02:57,941 INFO  [stdout] (default task-1)             (CreatedDate, InstanceId, ProfileId, QuestionId, UpdatedDate, Value, Id) 
08:02:57,941 INFO  [stdout] (default task-1)         values
08:02:57,941 INFO  [stdout] (default task-1)             (?, ?, ?, ?, ?, ?, ?)

Q1 :誰能告訴我為什么它不起作用?

Q2 :另外,在我從GenerationType.IDENTITY切換到GenerationType.SEQUENCE后,我開始在日志中收到以下異常:

[jdbc.spi.SqlExceptionHelper] – SQL Error: 544, SQLState: S0001
[jdbc.spi.SqlExceptionHelper] – Cannot insert explicit value for identity column in table 'Answers' when IDENTITY_INSERT is set to OFF.

是因為id列具有identity屬性嗎? 如果是,解決它的步驟是什么?

更新:我剛剛注意到我有一個錯誤的屬性名稱<prop key="hibernate.hibernate.jdbc.batch_size">5</prop> ,它應該是<prop key="hibernate.jdbc.batch_size">5</prop>

所以現在的主要問題

[jdbc.spi.SqlExceptionHelper] – SQL Error: 544, SQLState: S0001
[jdbc.spi.SqlExceptionHelper] – Cannot insert explicit value for identity column in table 'Answers' when IDENTITY_INSERT is set to OFF.

有什么想法可以解決嗎?

我面臨着完全相同的問題。 問題是在由 JPA 創建的表中,ID 列被標記為 IDENTITY 列,因此在由 JPA 生成的插入語句中這些 ID 列的顯式值被 MSSql 服務器阻止。 另一個有趣的事實是,如果您通過 IntelliJ 數據庫功能創建了“有問題的”表,並且您已將 ID 列注釋為主鍵和自動增量,那么它也會被標記為 IDENTITY 列。 所以解決方案如下:

  1. 右鍵單擊“有問題”表 -> SQL 腳本 -> 生成 DDL 以查詢控制台
  2. 放下桌子
  3. 從生成的查詢中刪除“身份”關鍵字
  4. 執行更改后的查詢
  5. 重啟數據庫中的序列:ALTER SEQUENCE answer_new_sequence RESTART WITH 1;
  6. 我強烈建議 allocationSize 值與 hibernate.hibernate.jdbc.batch_size 值匹配,因為這將導致序列中的最小傳遞值。 此外,allocationSize 必須與數據庫中序列的步驟相匹配。 希望這會有所幫助。 干杯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM