我在这个配置中基本上有一些对象(真正的数据模型有点复杂):
inverse="true")cascade设定"save-update")另外,我应该提一下主键是在保存时由数据库生成的.
对于我的数据,我有时会遇到A有一组不同B对象的问题,这些B对象引用相同的C对象.
当我打电话时session.saveOrUpdate(myAObject),我得到一个休眠错误说:"a different object with the same identifier value was already associated with the session: C".我知道hibernate不能在同一个会话中两次插入/更新/删除同一个对象,但有什么方法可以解决这个问题吗?这似乎不是一种不常见的情况.
在我研究这个问题的过程中,我看到人们建议使用session.merge(),但是当我这样做时,任何"冲突"对象都会作为空白对象插入到数据库中,所有值都设置为null.显然,这不是我们想要的.
[编辑]我忘记提到的另一件事是(由于我无法控制的架构原因),每次读取或写入都需要在单独的会话中完成.
jbx*_*jbx 82
很可能是因为B对象不是指同一个Java C对象实例.它们指的是数据库中的同一行(即相同的主键),但它们是它的不同副本.
所以正在发生的事情是管理实体的Hibernate会话将跟踪哪个Java对象对应于具有相同主键的行.
一种选择是确保引用同一行的对象B的实体实际上是指C的同一对象实例.或者关闭该成员变量的级联.这种方式当B持久存在时C不是.您必须单独手动保存C. 如果C是类型/类别表,那么这样做可能是有意义的.
dsk*_*dsk 11
你只需要做一件事.运行session_object.clear()然后保存新对象.这将清除会话(如命名),并从会话中删除有问题的重复对象.
我同意@Hemant Kumar,非常感谢。根据他的解决方案,我解决了我的问题。
例如?
@Test
public void testSavePerson() {
try (Session session = sessionFactory.openSession()) {
Transaction tx = session.beginTransaction();
Person person1 = new Person();
Person person2 = new Person();
person1.setName("222");
person2.setName("111");
session.save(person1);
session.save(person2);
tx.commit();
}
}
Run Code Online (Sandbox Code Playgroud)
人.java
public class Person {
private int id;
private String name;
@Id
@Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Basic
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码在我的应用程序中总是会犯错误:
A different object with the same identifier value was already associated with the session,后来我发现我忘了自动增加主键!
我的解决方案是在您的主键上添加以下代码:
@GeneratedValue(strategy = GenerationType.AUTO)
Run Code Online (Sandbox Code Playgroud)
小智 8
这意味着您正在尝试使用对同一对象的引用在表中保存多行。
检查您的实体类的 id 属性。
@Id
private Integer id;
Run Code Online (Sandbox Code Playgroud)
到
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(unique = true, nullable = false)
private Integer id;
Run Code Online (Sandbox Code Playgroud)
使用以下命令将从Hibernate分配对象ID的任务转移到数据库:
<generator class="native"/>
Run Code Online (Sandbox Code Playgroud)
这解决了我的问题.
另一种情况是可以自定义生成相同的错误消息allocationSize:
@Id
@Column(name = "idpar")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "paramsSequence")
@SequenceGenerator(name = "paramsSequence", sequenceName = "par_idpar_seq", allocationSize = 20)
private Long id;
Run Code Online (Sandbox Code Playgroud)
不匹配
alter sequence par_idpar_seq increment 20;
Run Code Online (Sandbox Code Playgroud)
可能会在插入期间导致约束验证(这一点很容易理解)或“具有相同标识符值的不同对象已与会话关联” - 这种情况不太明显。