我有两个对象以下列方式相互关联:
Item.java
@Entity
@Table(name = "item")
public class Item {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "item", cascade=CascadeType.ALL)
private Set<ItemConfiguration> ItemSettings = new HashSet<ItemSettings>();
}
ItemSetting.Java
@Entity
@Table(name = "item_setting")
public class ItemSetting {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@Column(name = "type")
private String type;
@Column(name = "value")
private String value;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id", nullable = false)
private Item item;
}
我正在尝试通过以下语句更新订单的设置:
ItemSettings settings = item.getSettingByType(type); // returns one of the settings that has matching type
settings.setValue("new value");
this.itemDAO.updateItem(item);
这会导致异常:
已经有一个具有相同标识符值的不同对象 与会话相关联
我不明白为什么会这样。我没有多次从数据库加载相同的setting
。方法item.getSettingByType(type)
通过迭代与项关联的一组设置来获取setting
。
答案 0 :(得分:0)
最有可能是因为Item对象不是指同一个Java ItemSetting对象实例。它们指的是数据库中的同一行(即相同的主键),但它们是它的不同副本。
所以正在发生的事情是管理实体的Hibernate会话将跟踪哪个Java对象对应于具有相同主键的行。
一种选择是确保引用同一行的对象Item实体实际引用ItemSetting的同一对象实例。或者,关闭该成员变量的级联。这种方式当Item持久化时,ItemSetting不是。您必须单独手动保存ItemSetting。如果ItemSetting是一个类型/类别表,那么这样做可能是有意义的。