I82*_*uch 6 java sql hibernate relational-database unique-constraint
我是Hibernate和DBs的新手,所以请原谅这个基本问题.
我正在使用DIS协议,特别是DIS的Open-DIS实现.在DIS中,每个EntityStatePdu(包含模拟中实体的状态)都有一个EntityId对象,一个3个整数的元组.我想将此对象用作自然ID,并保持标准的代理ID.我的问题是我无法弄清楚如何确保DB确定给定的EntityId已经存在并使用该EntityId的主键作为EntityStatePdu中的外键.
换句话说,假设我有两个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
Run Code Online (Sandbox Code Playgroud)
以下是我正在测试的简化类:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
和
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试通过以下方式将两个TestEntity对象存储到具有两个单独的TestId对象(在具有相同的站点,应用程序和实体方面相同)的DB中:
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();
}
Run Code Online (Sandbox Code Playgroud)
我在session2.save(entity2)行上获得了一个很长的堆栈跟踪,其中显着的是
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '2-3-1' for key 'app'
Run Code Online (Sandbox Code Playgroud)
我希望这很清楚.谢谢.
当您将某些字段标记为自然 ID 时,这意味着在该上下文中这些字段的组合将是唯一的,因此,例如,如果您有一个名为 person 的类,其名字和姓氏为自然 ID,则可能只有一个实体以 John 作为其FirstName 和 Smith 作为其 LastName。(类似于唯一索引)
在你的代码中:
TestId id1 = new TestId(1,2,3);
Run Code Online (Sandbox Code Playgroud)
和
TestId id2 = new TestId(1,2,3);
Run Code Online (Sandbox Code Playgroud)
指的是具有相同自然 ID 的两个不同实体,因此它们不能同时保存到数据库中。
| 归档时间: |
|
| 查看次数: |
3103 次 |
| 最近记录: |