这是一个简单的hibernate代码,可以将值插入表中。 如果该行已存在,请查询该行并返回数据。 大多数情况下,代码工作正常,没有任何问题。
在一个非常特殊的情况下,三个不同的客户端试图将完全相同的行插入表中。当然,只插入一行。其他两个插入失败,落入try-catch块。
try catch块中有一个查询,它查询数据并将值发送给客户端。这会导致会话后续操作出错。
Hibernate抛出“ERROR org.hibernate.AssertionFailure - 一个断言 失败发生(这可能表明Hibernate中存在错误,但更多 可能是由于会话的不安全使用)“在日志中。
这是代码。处理这种情况的正确方法是什么?
@Override
public void addPackage(PackageEntity pkg) {
try{
getCurrentSession().save(pkg);
getCurrentSession().flush();
}catch( ConstraintViolationException cve ){
// UNIQ constraint is violated
// query now, instead of insert
System.out.println("Querying again because of UNIQ constraint : "+ pkg);
PackageEntity p1 = getPackage(pkg.getName(), pkg.getVersion());
if( p1 == null ){
// something seriously wrong
throw new RuntimeException("Unable to query or insert " + pkg);
}else{
pkg.setId(p1.getId());
}
}catch (Exception e) {
e.printStackTrace();
}catch (Throwable t) {
t.printStackTrace();
}
}
答案 0 :(得分:0)
主要(或)复合键使每行数据都唯一,并避免此错误。
如果您需要来自所有这三个请求的数据,那么在表中创建一个唯一的主键并将其添加到实体。
主键可以是您数据中的任何唯一内容,自动生成的序列或UUID / GUID。