具有SequenceGenerator的javax.persistence.EntityExistsException [英] javax.persistence.EntityExistsException with SequenceGenerator

查看:51
本文介绍了具有SequenceGenerator的javax.persistence.EntityExistsException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Oracle DB中插入一些记录.对于唯一性,我正在使用SequenceGenerator.下面是代码:

I am inserting some records in Oracle DB. For the uniqueness, I am using SequenceGenerator. Below is the code:

public class XxspPoInLineLocqty implements Serializable {
    @Id 
    @SequenceGenerator(name = "SequenceLocIdGenerator", sequenceName = "LINE_LOCQTY_JPA_ID_SQ")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SequenceLocIdGenerator")
    @Column(name="LINE_LOCQTY_JPA_ID")
    private Long lineLocqtyJPAId;

//other fields..
}

XxspPoInLineLocqty与XxspPoInLine具有@ManyToOne关系.当我保留XxspPoInLine实体时,我收到以下错误:

XxspPoInLineLocqty is having @ManyToOne relation with XxspPoInLine. When I am persisting XxspPoInLine entity, I am receiving below error:

javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [com.bcone.oracle.ebs.model.XxspPoInLineLocqty#76]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:116)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:162)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:804)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:764)
    at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:80)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:391)

我查看了stackoverflow并找到了一些解决方案: 1.使用allocationSize = 1 因为我有5000+ XxspPoInLineLocqty,所以这是我可以应用的最差的选择.我也尝试过此方法,但是40分钟后,我的网络开始波动,并且持续失败.我不能使用此选项,因为它会降低性能.

I looked on the stackoverflow and found some solutions for this: 1. Use allocationSize=1 Since I am having 5000+ XxspPoInLineLocqty , this would be the worst option I could apply. I tried this as well but after 40min my network got fluctuate and persisting got failed. I cannot use this option as it degrade the performance.

2.增加分配大小的值 我增加了allocationSize = 500,但是在不同的标识符(#372)上仍然遇到相同的问题.

2. Increse the value of allocation size I increased the allocationSize=500, but still faced the same issue at different identifier(#372).

javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [com.bcone.oracle.ebs.model.XxspPoInLineLocqty#-372]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:116)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:162)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:804)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:764)
    at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:80)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:391)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:316)

甚至尝试过 GenerationType.AUTO ,但没有成功. 下面是Oracle DB上的序列:

Even tried GenerationType.AUTO, but no luck. Below is the sequence on Oracle DB:

CREATE SEQUENCE  "APPS"."LINE_LOCQTY_JPA_ID_SQ"  MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 7641 CACHE 20 NOORDER  NOCYCLE ;

我仍然很困惑为什么出现此问题.我不明白这的根本原因.有人可以向我解释此异常的根本原因,应该如何解决?

I am still confused why this issue is coming up. I didn't understand the root cause of this. Can someone explain me the root cause of this exception, and what should be the work around?

注意:在插入记录之前,我从表中删除了所有行.因此,当我执行上述顺序代码时,该表为空白.

Note : Before inserting the records, I deleted all the rows from table. So the table is blank when I execute the above sequnce code.

推荐答案

allocationSize参数必须与序列的INCREMENT BY值匹配.

allocationSize parameter must match the INCREMENT BY value of the sequence.

它的工作方式是,Hibernate从序列(从数据库)中获取一个值,然后将该值保留在内存中,并生成下一个X后续标识符(其中X = allocationSize),该标识符在该值中递增1.内存,而无需访问数据库.

It works in such a way that Hibernate gets a value from the sequence (from the database), and then keeps that value in the memory and generates next X subsequent identifiers (where X=allocationSize) incrementing this value by 1 in the memory, without reaching for the database.

一旦Hibernate生成X个标识符,它将从序列中获取下一个值,并生成新的X个标识符,将该值加1

Once Hibernate generates X identifiers, it gets the next value from the sequence, and generates new X identifiers, incrementing that value by 1

一个简单的例子-假设:

A simple example - let say that:

  • @SequenceGenerator( ....allocationSize=5 ...)
  • CREATE SEQUENCE .... INCREMENT BY 1 ...
  • @SequenceGenerator( ....allocationSize=5 ...)
  • CREATE SEQUENCE .... INCREMENT BY 1 ...

在上述情况下,休眠:

  1. 从序列中获取第一个数字-假设NextVal = 1并将其存储在内存中
  2. 生成下一个allocationSize=5标识符,使上述值加1,即:Id = 1, 2, 3, 4, 5
  3. 从序列中获取下一个数字-由于INCREMENT BY 1nextVal将为:2
  4. 生成下一个allocationSize=5标识符,使上述值加1,即:Id = 2, 3, 4, 5, 6
  1. Fetches the first number from the sequence - let say NextVal = 1 and stores it in the memory
  2. Generates next allocationSize=5 identifiers incrementing the above value by 1, that is: Id = 1, 2, 3, 4, 5
  3. Fetches the next number from the sequence - because of INCREMENT BY 1, the nextVal will be: 2
  4. Generates next allocationSize=5 identifiers incrementing the above value by 1, that is: Id = 2, 3, 4, 5, 6

如您所见,它将导致双重错误.

现在请考虑这种情况:

  • @SequenceGenerator( ....allocationSize=5 ...)
  • CREATE SEQUENCE .... INCREMENT BY 5 ...
  • @SequenceGenerator( ....allocationSize=5 ...)
  • CREATE SEQUENCE .... INCREMENT BY 5 ...

在这种情况下,休眠:

  1. 从序列中获取第一个数字-假设NextVal = 1并将其存储在内存中
  2. 生成下一个allocationSize=5标识符,使上述值加1,即:Id = 1, 2, 3, 4, 5
  3. 从序列中获取下一个数字-由于INCREMENT BY 5nextVal将为:6
  4. 生成下一个allocationSize=5标识符,使上述值加1,即:Id = 6, 7, 8, 9, 10
  1. Fetches the first number from the sequence - let say NextVal = 1 and stores it in the memory
  2. Generates next allocationSize=5 identifiers incrementing the above value by 1, that is: Id = 1, 2, 3, 4, 5
  3. Fetches the next number from the sequence - because of INCREMENT BY 5, the nextVal will be: 6
  4. Generates next allocationSize=5 identifiers incrementing the above value by 1, that is: Id = 6, 7, 8, 9, 10

在这种情况下,没有重复的错误.

最后一种情况的缺点是,如果该序列在Hibernate之外使用,则该序列会产生缺口.

The last case has the disadvantage that if the sequence is used outside of Hibernate, then the sequence will produce gaps.

这篇关于具有SequenceGenerator的javax.persistence.EntityExistsException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆