SequenceGenerator生成负值并引发EntityExistsException

时间:2018-10-18 10:42:53

标签: hibernate spring-data-jpa oracle12c

我已经按照如下方式定义了我的实体bean

public class Person implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="PERSON_SEQ")
@SequenceGenerator(name="PERSON_SEQ", sequenceName="PERSON_SID_SEQ")
@Column(name = "PERSON_SID")
private BigDecimal personSid;

我正在使用带有Oracle 12C数据库的Spring-data-jpa 2.0.5引导应用程序。我们的数据库序列定义为

CREATE SEQUENCE  "PERSON_SID_SEQ"  MINVALUE 1 MAXVALUE 
9999999999999999999999999999 INCREMENT BY 1 START WITH 1

我的应用程序需要插入大量记录,每个请求将近6000个或更多记录,并且我可能会收到这样数量的并行请求。要启用批量插入,我需要进行一些设置

spring.jpa.properties.hibernate.jdbc.batch_size=50
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.jdbc.batch_versioned_data=true

我还在每50条记录中使用jpaRepository.saveAll(),并在每50条记录后调用flush()。但是,当我使用上面定义的序列生成器时,只能看到一个

select person_sid_seq.nextval from dual

后跟50个insert语句。但是最终以异常失败

javax.persistence.EntityExistsException: A different object with the same 
identifier value was already associated with the session : 
[com.sample.Person#1]

不仅如此,我还注意到生成的序列号是负值。好像它们不是来自Person_sid_seq

使用save()方法而不是saveAll()时,我会看到相同的行为。

但是,如果我删除@SequenceGenerator和@GeneratedValue,并设置ID,则在调用save之前,我看不到持久性的任何问题(当然,在每次插入之前都会注意选择,不知道为什么)。

但是我的目的不是明确分配ID,而是让DB和JPA自动处理它。

1)可能是什么原因,返回的序列号为负?我是否缺少任何设置? 2)当依靠DB从序列中为我分配一个唯一值时,为什么会有一个异常(EntityExistsException)。可能是1,也会回答这个 3)以编程方式设置ID时,为什么要调用额外的选择。 ?

能帮我理解吗?

谢谢

0 个答案:

没有答案