简体   繁体   English

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

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

I used this article to implement batch inserts with spring-data-jpa for one of my entities.我使用本文为我的一个实体使用 spring-data-jpa 实现批量插入。 I am using MS SQL DB.我正在使用 MS SQL 数据库。

I changed the primary key generation strategy from GenerationType.IDENTITY to GenerationType.SEQUENCE :我将主键生成策略从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;
    }

The service method saves list of answer entities by calling <S extends T> List<S> save(Iterable<S> entities);服务方法通过调用<S extends T> List<S> save(Iterable<S> entities);答案实体列表。 :

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

To tell Hibernate to use batching while inserts and check it is actually working, I set following JPA properties:为了告诉 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>

However, upon inserting 11 entities the JDBC batches count is 0:但是,在插入 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 queries: 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 : Can anyone tell me why it is not working? Q1 :谁能告诉我为什么它不起作用?

Q2 : Also, after I switched from GenerationType.IDENTITY to GenerationType.SEQUENCE , I started getting following exceptions in the logs: 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.

Is it because id column has identity property?是因为id列具有identity属性吗? If yes, what would be the steps to solve it?如果是,解决它的步骤是什么?

UPDATED: I just noticed that I have a wrong property name <prop key="hibernate.hibernate.jdbc.batch_size">5</prop> , it should be <prop key="hibernate.jdbc.batch_size">5</prop> .更新:我刚刚注意到我有一个错误的属性名称<prop key="hibernate.hibernate.jdbc.batch_size">5</prop> ,它应该是<prop key="hibernate.jdbc.batch_size">5</prop>

So the main problem now is the所以现在的主要问题

[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.

Any ideas how I can solve it?有什么想法可以解决吗?

I was facing the exact same issue.我面临着完全相同的问题。 The problem is that in the tables created by the JPA, the ID columns are flagged as IDENTITY columns and as a consequence the exlpicit values for these ID columns in the insert statements that are generated by the JPA are blocked by the MSSql Server.问题是在由 JPA 创建的表中,ID 列被标记为 IDENTITY 列,因此在由 JPA 生成的插入语句中这些 ID 列的显式值被 MSSql 服务器阻止。 Another interesting fact is that if you have created the "problematic" tables via the IntelliJ Database functionality and you have annotated the ID column as Primary Key and Auto-Increment then it is flagged as IDENTITY column as well.另一个有趣的事实是,如果您通过 IntelliJ 数据库功能创建了“有问题的”表,并且您已将 ID 列注释为主键和自动增量,那么它也会被标记为 IDENTITY 列。 So the solution is the following:所以解决方案如下:

  1. Right click on the "problematic" table -> SQL Scripts -> Generate DDL to query console右键单击“有问题”表 -> SQL 脚本 -> 生成 DDL 以查询控制台
  2. Drop the table放下桌子
  3. Delete the "identity" keyword from the generated query从生成的查询中删除“身份”关键字
  4. Execute the altered query执行更改后的查询
  5. Restart the sequence in the DB: ALTER SEQUENCE answer_new_sequence RESTART WITH 1;重启数据库中的序列:ALTER SEQUENCE answer_new_sequence RESTART WITH 1;
  6. I strongly suggest that the allocationSize value matches the hibernate.hibernate.jdbc.batch_size value as this will result in the minimum passed over values from the sequence.我强烈建议 allocationSize 值与 hibernate.hibernate.jdbc.batch_size 值匹配,因为这将导致序列中的最小传递值。 Also the allocationSize must match the step of the sequence in the DB.此外,allocationSize 必须与数据库中序列的步骤相匹配。 Hopefully this helps.希望这会有所帮助。 Cheers.干杯。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM