我是新來的Hibernate和數據庫一般,所以請原諒基本問題。休眠自然ID重複問題
我正在與DIS protocol合作,特別是DIS的Open-DIS實現。在DIS中,每個EntityStatePdu(包含模擬中實體的狀態)都有一個EntityId對象,一個由3個整數組成的元組。我想將此對象用作自然ID,並且還維護標準的代理ID。我的問題是我無法弄清楚如何確保數據庫確定給定的EntityId已經存在,並使用該EntityId的主鍵作爲EntityStatePdu中的外鍵。換句話說,我說有兩個EntityStatePdus,EntityID(1,2,3);如果我有兩個EntityStatePdus,EntityID(1,2,3);即我們有來自同一個實體的兩個更新。我希望像下面這樣:
表:
entity_id
pk site app entity
0 1 2 3
entity_state_pdu
pk entity_id_fk timestamp
0 0 1
1 0 2
這裏是簡化類我與測試:
@Entity
public class TestEntity {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@NaturalId
@ManyToOne(cascade = CascadeType.ALL)
private TestId naturalId;
public Long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public TestId getNaturalId() {
return naturalId;
}
public void setNaturalId(TestId naturalId) {
this.naturalId = naturalId;
}
}
和
@Entity
public class TestId {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@NaturalId
private int site;
@NaturalId
private int app;
@NaturalId
private int entity;
public TestId(int site, int app, int entity) {
this.site = site;
this.app = app;
this.entity = entity;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getSite() {
return site;
}
public void setSite(int site) {
this.site = site;
}
public int getApp() {
return app;
}
public void setApp(int app) {
this.app = app;
}
public int getEntity() {
return entity;
}
public void setEntity(int entity) {
this.entity = entity;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + app;
result = prime * result + entity;
result = prime * result + site;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TestId other = (TestId) obj;
if (app != other.app)
return false;
if (entity != other.entity)
return false;
if (site != other.site)
return false;
return true;
}
}
我嘗試存儲將兩個TestEntity對象分成兩個獨立的TestId對象(這些對象具有相同的站點) ,應用程序和實體)的方式如下:
public static void main(String[] args) {
SessionFactory factory = createFactory();
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
TestId id1 = new TestId(1,2,3);
TestEntity entity1 = new TestEntity();
entity1.setNaturalId(id1);
session.save(entity1);
tx.commit();
session.close();
Session session2 = factory.openSession();
Transaction tx2 = session2.beginTransaction();
TestId id2 = new TestId(1,2,3);
TestEntity entity2 = new TestEntity();
entity2.setNaturalId(id2);
session2.save(entity2);
tx2.commit();
session2.close();
}
我弄了半天堆棧跟蹤的session2.save(ENTITY2)線,以突出線是
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '2-3-1' for key 'app'
我希望這是足夠清楚。謝謝。
在這個例子中,ID對象是一個接一個地創建的。在真正的應用程序中,我們反序列化一個字節流,並在該反序列化過程中爲每個EntityStatePdu實例化一個新的EntityId對象。但從邏輯上講,它代表着與數據庫中已有的EntityId完全相同的EntityId,即具有相同的(site,app,entityId)三元組。 – I82Much 2011-05-19 13:03:51