0

我正在尝试批量插入一个List对象。我将 ID 配置为自动生成。以前我有以下内容:

<id name="entryId" type="integer"  column="ENTRY_ID">
    <generator class="seqhilo"> 
        <param name="sequence">HB_ENTRY_ID_SEQ</param>
        <param name="max_lo">50</param>
    </generator>
</id>

我的插入查询如下:

try (Session session = sessionFactory.openSession()) {
    session.beginTransaction();

    for (int i = 0; i < insertList.size(); i++) {
        session.save(insertList.get(i));
        if (i % 100 == 0) {
            session.flush();
            session.clear();
        }
    }

    session.getTransaction().commit();
    return insertList.size();
}

我也batch_size设置了正确的属性值。以上工作正常,但是,最近我将代码更改为基于注释,并且我有以下内容:

@Id
@Column(name = "ENTRY_ID")
@GeneratedValue(generator = "hibSeq", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "hibSeq", sequenceName = "HB_ENTRY_ID_SEQ", allocationSize = 100)

当我现在运行它时,插入会抛出一个org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session

我一直在尝试按照此处此处的方式理解此错误,但无法解决我的问题。据我所知,在这个session.flush()/clear()阶段发生了一些事情,导致序列生成器回收一个已经使用过的 ID。

我究竟做错了什么?

4

1 回答 1

0

XML 中提供的生成器与注解指定的生成器不同。前者是一个序列hilo,它会根据一个序列返回的值生成一个ID前缀。

后者获取序列的值:它将该值和下一个 100 保存在内存中(根据allocationSize),这使您可以避免进行 100 次调用。但是,在生成了 100 个 ID 之后,它会调用 nextval 并生成与第二个条目相同的 ID:

Generated ID 0 (query) .NEXTVAL
Generated ID 1 (in memory)
Generated ID 2 (in memory)
...
Generated ID 100 (in memory)
Generated ID 1 (query) .NEXTVAL

这里的解决方案是ALTER SEQUENCE HB_ENTRY_ID_SEQ INCREMENT BY 100

于 2016-03-29T18:33:04.217 回答