具有SequenceGenerator的javax.persistence.EntityExistsException [英] javax.persistence.EntityExistsException with SequenceGenerator
问题描述
我正在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 ...
在上述情况下,休眠:
- 从序列中获取第一个数字-假设
NextVal = 1
并将其存储在内存中 - 生成下一个
allocationSize=5
标识符,使上述值加1,即:Id = 1, 2, 3, 4, 5
- 从序列中获取下一个数字-由于
INCREMENT BY 1
,nextVal
将为:2
- 生成下一个
allocationSize=5
标识符,使上述值加1,即:Id = 2, 3, 4, 5, 6
- Fetches the first number from the sequence - let say
NextVal = 1
and stores it in the memory - Generates next
allocationSize=5
identifiers incrementing the above value by 1, that is:Id = 1, 2, 3, 4, 5
- Fetches the next number from the sequence - because of
INCREMENT BY 1
, thenextVal
will be:2
- 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 ...
在这种情况下,休眠:
- 从序列中获取第一个数字-假设
NextVal = 1
并将其存储在内存中 - 生成下一个
allocationSize=5
标识符,使上述值加1,即:Id = 1, 2, 3, 4, 5
- 从序列中获取下一个数字-由于
INCREMENT BY 5
,nextVal
将为:6
- 生成下一个
allocationSize=5
标识符,使上述值加1,即:Id = 6, 7, 8, 9, 10
- Fetches the first number from the sequence - let say
NextVal = 1
and stores it in the memory - Generates next
allocationSize=5
identifiers incrementing the above value by 1, that is:Id = 1, 2, 3, 4, 5
- Fetches the next number from the sequence - because of
INCREMENT BY 5
, thenextVal
will be:6
- 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屋!