Hibernate Update Exception:具有相同标识符值的不同对象已与会话关联

时间:2017-04-25 15:29:47

标签: java hibernate

我有两个对象以下列方式相互关联:

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

1 个答案:

答案 0 :(得分:0)

最有可能是因为Item对象不是指同一个Java ItemSetting对象实例。它们指的是数据库中的同一行(即相同的主键),但它们是它的不同副本。

所以正在发生的事情是管理实体的Hibernate会话将跟踪哪个Java对象对应于具有相同主键的行。

一种选择是确保引用同一行的对象Item实体实际引用ItemSetting的同一对象实例。或者,关闭该成员变量的级联。这种方式当Item持久化时,ItemSetting不是。您必须单独手动保存ItemSetting。如果ItemSetting是一个类型/类别表,那么这样做可能是有意义的。