【问题标题】:javax.persistence.EntityExistsException with SequenceGenerator带有 SequenceGenerator 的 javax.persistence.EntityExistsException
【发布时间】:2019-02-24 15:45:26
【问题描述】:

我在 Oracle DB 中插入一些记录。为了唯一性,我使用的是 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$1.cascade(JpaPersistEventListener.java:80)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:391)

我查看了 stackoverflow 并找到了一些解决方案: 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$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 上的序列:

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

我仍然很困惑为什么会出现这个问题。我不明白这件事的根本原因。有人可以解释一下这个异常的根本原因吗?应该如何解决?

注意:在插入记录之前,我从表中删除了所有行。所以当我执行上面的序列代码时,表格是空白的。

【问题讨论】:

    标签: java oracle hibernate jpa-2.0


    【解决方案1】:

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

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

    一旦 Hibernate 生成 X 标识符,它会从序列中获取下一个值,并生成新的 X 标识符,并将该值加 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

    如您所见,它会导致重复错误。


    现在请考虑这个案例:

    • @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

    在这种情况下没有重复错误。


    最后一种情况的缺点是如果序列在Hibernate之外使用,那么序列会产生间隙。

    【讨论】:

      猜你喜欢
      • 2013-12-27
      • 2012-10-22
      • 1970-01-01
      • 1970-01-01
      • 2020-08-22
      • 2012-09-26
      • 2011-11-19
      • 1970-01-01
      相关资源
      最近更新 更多