【问题标题】:javax.persistence.EntityExistsException: A different object with the same identifier valuejavax.persistence.EntityExistsException:具有相同标识符值的不同对象
【发布时间】:2020-08-22 19:52:25
【问题描述】:

以前我没有收到任何错误,但突然我开始收到错误:

javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [baag.betl.dbimporter.esmatrans.db.EquSecurityReferenceData#baag.db.SECU@59c70ceb]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:116) ~[hibernate-core-5.2.10.Final.jar:5.2.10.Final]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155) ~[hibernate-core-5.2.10.Final.jar:5.2.10.Final]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:162) ~[hibernate-core-5.2.10.Final.jar:5.2.10.Final]
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:787) ~[hibernate-core-5.2.10.Final.jar:5.2.10.Final]
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:765) ~[hibernate-core-5.2.10.Final.jar:5.2.10.Final]

没有为 oracle 数据库表中的任何列创建序列。还有 esn 和 techid 的唯一键列的组合。我不想在我的数据库表中创建新的序列列。

我认为我不能使用 @GeneratedValue 并将其设置为 Auto 用于唯一列,否则我会收到休眠序列错误。

我也在每处理 1000 条记录后进行清除和刷新。

if (secuData != null) {
                sessionFactory.getCurrentSession().persist(secuData);
}

i++;
    if (i % 1000 == 0) {
                sessionFactory.getCurrentSession().flush();
                sessionFactory.getCurrentSession().clear();
    }

【问题讨论】:

    标签: java spring hibernate exception sequence


    【解决方案1】:

    要拥有复合主键,您可以使用@IdClass@Embeddable 键方法。

    要继续使用@IdClass 方法,您需要遵循一些规则,

    • 复合主键类必须是公共的
    • 它必须有一个无参数的构造函数
    • 必须定义equals()和hashCode()方法
    • 它必须是可序列化的

    所以在你的情况下,这个类看起来像,

    @Entity
    @Table( name = "SECU" )
    @IdClass( SECU.class )
    public class SECU implements Serializable
    {
    
        @Id
        @Column(name = "columnName") // use the correct column name if it varies from the variable name provided
        protected String esn;
    
        @Id
        @Column(name = "columnName") // use the correct column name if it varies from the variable name provided
        protected BigDecimal techrcrdid;
    
        @Column(name = "columnName") // use the correct column name if it varies from the variable name provided
        protected BigDecimal preTradLrgInScaleThrshld;
    
        @Column(name = "columnName") // use the correct column name if it varies from the variable name provided
        @Temporal( TemporalType.TIMESTAMP)
        protected LocalDateTime CreDt;
    
        @Column(name = "columnName") // use the correct column name if it varies from the variable name provided
        protected String fullnm;
    
        @Override
        public boolean equals( Object o )
        {
            if( this == o ) return true;
            if( !( o instanceof SECU ) ) return false;
            SECU secu = ( SECU ) o;
            return Objects.equals( esn, secu.esn ) &&
                           Objects.equals( techrcrdid, secu.techrcrdid ) &&
                           Objects.equals( preTradLrgInScaleThrshld, secu.preTradLrgInScaleThrshld ) &&
                           Objects.equals( CreDt, secu.CreDt ) &&
                           Objects.equals( fullnm, secu.fullnm );
        }
    
        @Override
        public int hashCode()
        {
            return Objects.hash( esn, techrcrdid, preTradLrgInScaleThrshld, CreDt, fullnm );
        }
    
        // getters and setters 
    }
    

    还要仔细检查每个实体类中的 getter 和 setter,您的问题中提供的一次似乎不正确。

    【讨论】:

    • 它工作正常 :) 但我只需要知道 equals() 和 hashCode() 方法在这里做什么来解决问题?
    • @Andrew 如果这有帮助,请将答案标记为已接受。对于您的问题,您可以查看stackoverflow.com/questions/22646456/…,我引用,“当主键不是复合键时,它们通常是Integer, Long, String 的基本支持类型,它们的equalshashcode 方法很好已定义。”
    【解决方案2】:

    您的实体类似乎在为复合主键建模,但我只看到 2 个 @Id 并且没有使用必要的 @IdClass 注释。

    【讨论】:

    猜你喜欢
    • 2018-02-13
    • 2013-08-30
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 2012-08-23
    • 2020-08-03
    • 1970-01-01
    相关资源
    最近更新 更多