簡體   English   中英

Hibernate - 在使用復合主鍵(@idClass)時,無法在保留其自動生成的屬性時插入新記錄

[英]Hibernate - Cannot insert new record when using composite primary key (@idClass), given keeping its auto-generated attribute

我會試着簡單一點。 我有一個表,其中包含由兩個Long屬性組成的復合主鍵,由@IdClass帶注釋的類包裝。

@IdClass屬性:

public class MyPK implements Serializable {
    private Long id;
    private Long version;
} // + hashCode, constructors, etc.

我未能做到的事情:

在保持“id”值並遞增“version”的同時插入新記錄。

示例場景:

現有記錄 - {id:1,version:1}

期望的新記錄(未更新,談論新記錄) - {id:1,version:2}

我做了什么:

起初我嘗試在保持我正在使用的序列生成器的同時遞增版本。 以下是id的注釋方式:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idSequence")
@SequenceGenerator(name = "idSequence", sequenceName = "SQ_ID", allocationSize = 1)
@Column(name = "ID", nullable = false, updatable = false)
private Long id;

上面導致提供的id被序列的nextVal覆蓋,所以對我沒有任何處理。

所以我的第二種方法是使用繼承和內部Hibernate類,我總是試圖避免:

public class MySequenceStyleIdGenerator extends SequenceStyleGenerator {

    @Override
    public Serializable generate(SessionImplementor session, Object object){
        Serializable id = session.getEntityPersister(null, object)
                .getClassMetadata().getIdentifier(object, session);

        return id != null && ((MyPK)id).getId() != null
                ? id : super.generate(session, object);
    }

}

並根據需要對實體類進行更改:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "providedIdOrSequence")
@GenericGenerator(
        name="providedIdOrSequence",
        strategy="{package}.MySequenceStyleIdGenerator",
        parameters = @org.hibernate.annotations.Parameter(
                name = "sequence_name",
                value = "SQ_ID"
        )
)
@Column(name = "ID", nullable = false, updatable = false)
private Long id;

另一方面,當它為null時,它將nextVal返回到id,這就是我想要的。 然后問題轉移到庫中更深和更深的東西,就好像它試圖將id(Long)分配給PK類型本身而不是它的Long屬性:

在此輸入圖像描述

java.lang.IllegalArgumentException:無法將java.lang.Long字段{package} .CotacaoPK.idCotacao設置為{package} .CotacaoPK

如果兩個PK屬性(id和version)保持不變,那么我沒有錯誤。

有任何想法嗎? 我已經花了一個合理的小時數...謝謝。

問題解決了!

問題出在我的SequenceStyleGenerator實現中。 super.generate(...)返回一個Long,但我返回id作為包裝MyPK對象。 所以解決方案是:

public class MySequenceStyleIdGenerator extends SequenceStyleGenerator {

@Override
public Serializable generate(SessionImplementor session, Object object){
        Serializable id = session.getEntityPersister(null, object)
                .getClassMetadata().getIdentifier(object, session);

        return id != null && ((MyPK)id).getId() != null
                ? ((MyPK)id).getId() : super.generate(session, object);
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM