簡體   English   中英

Hibernate復合ID合並

[英]Hibernate composite id merge

我正在將Hibernate與JPA結合使用,並具有如下關系:

@Entity
@Table(name = "first")
public class First {
...
@OneToMany(mappedBy = "first")
private List<Availability> availabilities;
...
}


@Entity
@Table(name = "second")
public class Second {
...
@OneToMany(mappedBy = "second")
private List<Availability> availabilities;
...
}

@Entity
@Table(name="availability")
public class Availability implements Serializable {
@Id
@ManyToOne
@JoinColumn(name = "first_id")
private First first;

@Id
@ManyToOne
@JoinColumn(name = "second_id")
private Second second;

@Column(name = "availability")
private Integer availability;

...
hashcode and equals
}

我想分別管理這三個實體。 第一和第二工作正常,但是當我嘗試merge()時,第三個postgresql獲取一個空值而不是id,並且拋出了違反約束的異常。 為什么? 我什至可以在此實體上使用merge將新行添加到表中?

更新:合並是這樣的:

public Availability setAvailability(Availability a) {
return em.merge(a);
}

可用性從前端反序列化(僅提及,“鍵”類的集合在其中分離)。

您已經解決了您的問題,但是對於需要使用多列主鍵且無法更改數據庫的用戶,我這里有一個建議。

顯然,嘗試合並時單獨使用多個@Id注釋會產生不一致:分配所有字段,然后在合並期間,用@Id注釋的字段將分配為空值 (合並失敗)。 我可以猜出一個解釋:休眠不希望有一個分配了@Ids的非托管對象; 但這僅是多個列主鍵的問題,因此似乎是一個錯誤。

注意:調用persist而不是merge可以工作(但是在某些情況下,您將復制行或獲取數據庫約束錯誤,因為在這種情況下,僅在數據庫級別檢查主鍵)。

我使用@IdClass解決了類似的問題。 在舊代碼中,您將必須:

  1. 創建一個具有第一個字段和第二個字段的類(例如, AvailabilityId )(與在Availability類中用@Id注釋的字段完全匹配),並覆蓋equalshashCode方法
  2. 除了@Override以外,在AvailabilityId中不需要任何注釋(順便說一句,如果同時在Availability和AvailabilityId字段上使用@Column,則可能會出現巨大錯誤)。 這不必是實體或表,它可以是POJO。
  3. 使用@IdClass(AvailabilityId.class)注釋類的可用性

應該是這樣。 抱歉,我們遲到了3年,但是如果您擺脫了多列主鍵,現在無論如何您都會處於一個更好的世界。

我嘗試了@EmbeddedId,但它打破了其他一些要求(輕松進行json-> object轉換以及在SQL和HQL中都可以進行細微調整的查詢)。

我通過避免使用Composite ID解決了該問題。 重新思考問題后,我發現這種情況實際上可以使用唯一約束。

@Entity
@Table(name = "availabilities", uniqueConstraints = { @UniqueConstraint(columnNames = {
    "first_id", "second_id" }) })
@SequenceGenerator(initialValue = 1, name = "availabilities_sequence", sequenceName =     "availabilities_sequence")
public class Availability implements IAvailability, Serializable {

private static final long serialVersionUID = -2977047920673617888L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "availabilities_sequence")
@Column(name = "id")
private Integer id;

@ManyToOne
@JoinColumn(name = "first_id", nullable=false)
private First first;

@ManyToOne
@JoinColumn(name = "second_id", nullable=false)
private Second second;

@Column(name = "availability", nullable=false)
private Integer availability;

...
}

暫無
暫無

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

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