javax.persistence.EntityExistsException 与序列生成器
javax.persistence.EntityExistsException with SequenceGenerator
我正在 Oracle 数据库中插入一些记录。为了唯一性,我使用的是 SequenceGenerator。下面是代码:
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 实体时,我收到以下错误:
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.cascade(JpaPersistEventListener.java:80)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:391)
我查看了 Whosebug 并找到了一些解决方案:
1。使用 allocationSize=1
由于我有 5000+ XxspPoInLineLocqty
,这将是我可以应用的最糟糕的选择。我也试过了,但 40 分钟后我的网络出现波动并且坚持失败。我无法使用此选项,因为它会降低性能。
2。增加分配大小的值
我增加了 allocationSize=500,但在不同的标识符 (#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.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 上的序列:
CREATE SEQUENCE "APPS"."LINE_LOCQTY_JPA_ID_SQ" MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 7641 CACHE 20 NOORDER NOCYCLE ;
我仍然很困惑为什么会出现这个问题。我不明白这的根本原因。有人可以向我解释此异常的根本原因吗?应该如何解决?
注意:在插入记录之前,我删除了 table 中的所有行。所以当我执行上面的sequnce代码时table是空白的。
allocationSize
参数必须匹配序列的 INCREMENT BY
值。
它的工作方式是 Hibernate 从序列(从数据库)中获取一个值,然后将该值保存在内存中并生成下一个 X 个后续标识符(其中 X=allocationSize)并将该值递增 1在内存中,无需访问数据库。
一旦 Hibernate 生成 X 标识符,它就会从序列中获取下一个值,并生成新的 X 标识符,将该值递增 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
如您所见,它会导致重复错误。
现在请考虑这个案例:
@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
本例中没有重复错误。
最后一种情况的缺点是如果序列在Hibernate之外使用,那么序列会产生空隙。
我正在 Oracle 数据库中插入一些记录。为了唯一性,我使用的是 SequenceGenerator。下面是代码:
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 实体时,我收到以下错误:
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.cascade(JpaPersistEventListener.java:80)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:391)
我查看了 Whosebug 并找到了一些解决方案:
1。使用 allocationSize=1
由于我有 5000+ XxspPoInLineLocqty
,这将是我可以应用的最糟糕的选择。我也试过了,但 40 分钟后我的网络出现波动并且坚持失败。我无法使用此选项,因为它会降低性能。
2。增加分配大小的值 我增加了 allocationSize=500,但在不同的标识符 (#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.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 上的序列:
CREATE SEQUENCE "APPS"."LINE_LOCQTY_JPA_ID_SQ" MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 7641 CACHE 20 NOORDER NOCYCLE ;
我仍然很困惑为什么会出现这个问题。我不明白这的根本原因。有人可以向我解释此异常的根本原因吗?应该如何解决?
注意:在插入记录之前,我删除了 table 中的所有行。所以当我执行上面的sequnce代码时table是空白的。
allocationSize
参数必须匹配序列的 INCREMENT BY
值。
它的工作方式是 Hibernate 从序列(从数据库)中获取一个值,然后将该值保存在内存中并生成下一个 X 个后续标识符(其中 X=allocationSize)并将该值递增 1在内存中,无需访问数据库。
一旦 Hibernate 生成 X 标识符,它就会从序列中获取下一个值,并生成新的 X 标识符,将该值递增 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
如您所见,它会导致重复错误。
现在请考虑这个案例:
@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
本例中没有重复错误。
最后一种情况的缺点是如果序列在Hibernate之外使用,那么序列会产生空隙。