[英]Symmetric composite key in jpa/hibernate
我正在嘗試確保模型不會在數據庫中保留兩次,並且其ID是對稱的。 在對稱組合id下,我的意思是:
@Entity
public class Item {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "item_id", unique = true, nullable = false)
public Long id;
// other properties ...
}
@Entity
public class Pair {
@EmbeddedId
public PairId id;
// other properties...
@Embeddable
public static class PairId implements Serializable {
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
@JoinColumn(name="source_item_id")
public Item source;
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
@JoinColumn(name="target_item_id")
public Item target;
@Override
public boolean equals(Object o) {
if(this == o){
return true;
}
if (o instanceof PairId == false){
return false;
}
PairId other = (PairId) o;
return (this.source.equals(other.source) && this.target.equals(other.target)) ||
(this.source.equals(other.target) && this.target.equals(other.source));
}
@Override
public int hashCode() { //probably not the best approach
return source.hashCode() + target.hashCode();
}
}
}
例:
Item i1 = new Item();
Item i2 = new Item();
//persist items into the database ...
PairId pId1 = new PairId(i1, i2);
PairId pId2 = new PairId(i2, i1);
Pair p1 = new Pair(pId1);
//persist p1 into the database
Pair p2 = new Pair(pId2);
//calling persist should not add new entry to the database, since p2 is symmetrical to p1 and already exists in the database
Pair p3 = findById(pId2);
//p3 should now contain p1 also
您是否知道我該如何實施這種行為? 提前致謝!
編輯:在這兩個類上添加了注釋,以表明這些類除了上面列出的ID之外,還可以具有(並且具有)其他屬性。 但是為了簡單起見,我只是將它們的ID保留為單獨的固定資產。
也許,也許您可以放棄Pair
想法並在Item
使用自我參考。 這樣,您的表就更少了,代碼更簡潔,也沒有復合鍵了。
碼:
@Entity
public class Item
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@OneToOne
@JoinColumn(name = "source_id", referencedColumnName = "id")
private Item source;
@OneToOne(mappedBy = "source")
private Item target;
}
首先,我不會使用復合ID。 使用自動生成的代理鍵,並將這兩項都存儲為常規屬性。
然后,當成對存儲項目時,我將確保始終以相同順序存儲它們。 例如,源ID應始終比目標ID小。 使用封裝可以確保這一點:
public void setItems(Item i1, Item i2) {
if (i1.getId().compareTo(i2.getId()) < 0) {
this.source = i1;
this.target = i2;
}
else {
this.source = i2;
this.target = i1;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.