[英]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.