簡體   English   中英

在具有復合主鍵的表上使用Spring JpaRepository(具有Hibernate 4作為提供程序)會拋出IdentifierGenerationException

[英]Using Spring JpaRepository, with Hibernate 4 as the provider, on a table with composite primary key throws an IdentifierGenerationException

如標題所示。 我有一個帶有復合鍵的實體。 實體是:

ContractServiceLocation.java

@Entity
@Table(name="CONTRACT_SERVICE_LOCATION")
@NamedQuery(name="ContractServiceLocation.findAll", query="SELECT c FROM ContractServiceLocation c")
@TypeDef(defaultForType= LocalDate.class, typeClass = LocalDateType.class)
public class ContractServiceLocation implements Serializable {
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private ContractServiceLocationPK id;

    @Column(nullable=false)
    private LocalDate datefrom;

    private LocalDate dateto;

    @Column(length=90)
    private String details;

    @Column(nullable=false, precision=65535, scale=32767)
    private BigDecimal price;

    //bi-directional many-to-one association to Contract
    @ManyToOne
    @JoinColumn(name="CONTRACT_ID", nullable=false, insertable=false, updatable=false)
    private Contract contract;

    //uni-directional many-to-one association to Location
    @ManyToOne
    @JoinColumn(name="LOCATION_ID", nullable=false, insertable=false, updatable=false)
    private Location location;

    //uni-directional many-to-one association to Service
    @ManyToOne
    @JoinColumn(name="SERVICE_ID", nullable=false, insertable=false, updatable=false)
    private Service service;

    //getters & setters
    }

ContractServiceLocationPK.java

@Embeddable
public class ContractServiceLocationPK implements Serializable {
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;

    @Column(name="CONTRACT_ID", insertable=false, updatable=false, unique=true, nullable=false)
    private long contractId;

    @Column(name="LOCATION_ID", insertable=false, updatable=false, unique=true, nullable=false)
    private long locationId;

    @Column(name="SERVICE_ID", insertable=false, updatable=false, unique=true, nullable=false)
    private long serviceId;

    //getters & setters & equals & hashcode
    }

由於我將JpaRepository用於所有其他實體,因此我認為它將支持帶有復合鍵的實體。 因此,我將Dao定義為:

ContractServiceLocationDao.java

@Repository
public interface ContractServiceLocationDao extends
        JpaRepository<ContractServiceLocation, ContractServiceLocationPK> {

}

但是,在ContractServiceLocation實體上調用save方法時,我得到:

org.springframework.orm.jpa.JpaSystemException: null id generated for:class hr.kingict.telco.model.ContractServiceLocation; nested exception is org.hibernate.id.IdentifierGenerationException: null id generated for:class hr.kingict.telco.model.ContractServiceLocation

我已經在調試中檢查了所有組合鍵屬性(合同,服務和位置)都不為空。 但是該異常顯示“為類生成了空ID ...”,因此我假設它以某種方式嘗試生成ID(即使我沒有設置@GeneratedValue批注)。

我該怎么做才能解決這個問題? 我是否必須手動編寫dao而不是依賴JpaRepository?

我想到了。 問題是,當我向實體添加合同,服務或位置時,我沒有更新id對象來反映這一點。 一旦我弄清楚,解決方案很簡單。 在具有組合鍵的實體中(在我的示例中為ContractServiceLocation.java),在組成組合鍵的屬性的設置器中添加了以下代碼:

public void setContract(Contract contract) {
    this.contract = contract;
    this.id.setContractId(contract.getId()); //added line
}

因此,每次我設置/更改復合屬性時,該ID都會反映出來。

同樣,這也不是完美的(但現在可以使用),可以通過檢查屬性id是否為null / default以及是否拋出異常來進行改進。

暫無
暫無

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

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