@ManyToMany错误未保存的瞬态实例或重复条目

时间:2013-01-25 14:57:26

标签: hibernate many-to-many

我在@ManyToMany关系中有2个实体:Networks和SiteCodes。

网络:

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "network_id")
public int getNetworkId() {
    return this.networkId;
}

public void setNetworkId(int networkId) {
    this.networkId = networkId;
}

@ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
@JoinTable(name = "site_code_map", 
joinColumns = { @JoinColumn(name = "network_id") },  
inverseJoinColumns = { @JoinColumn(name = "site_code_id") })
public Set<SiteCodes> getSiteCodes() {
    return siteCodes;
}

public void setSiteCodes(Set<SiteCodes> siteCodes) {
    this.siteCodes = siteCodes;
}

SiteCodes:

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "site_code_id")
public Integer getSiteCodeId() {
    return this.siteCodeId;
}

public void setSiteCodeId(Integer siteCodeId) {
    this.siteCodeId = siteCodeId;
}

@Column(name = "site_code", nullable = false)
@NotNull
@NaturalId
public String getSiteCode() {
    return siteCode;
}

@ManyToMany(mappedBy="siteCodes",cascade = CascadeType.MERGE)
public Set<Networks> getNetworks() {
    return networks;
}

public void setNetworks(Set<Networks> networks) {
    this.networks = networks;
}

我的主要课程:

session.beginTransaction();

Networks nw1 = new Networks(345);
Networks nw2 = new Networks(789);

SiteCodes sc1 = new SiteCodes("0123");
SiteCodes sc2 = new SiteCodes("0001");
SiteCodes sc3 = new SiteCodes("0ABC");

// The real code would do this inside a loop, ie create a new network, figure out 
// the site codes and assign them.
session.beginTransaction();
Networks nw1 = new Networks(345);
nw1.getSiteCodes().add(sc1);
nw1.getSiteCodes().add(sc2);
session.merge(nw1);
session.getTransaction().commit();

session.beginTransaction();
Networks nw2 = new Networks(789);
nw2.getSiteCodes().add(sc3);
nw2.getSiteCodes().add(sc2);
session.merge(nw2);
session.getTransaction().commit();

结果是重复输入错误:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '0001' for key 'site_code'

我玩过CascadeType以及我能想到的任何其他东西。我已经搜索了关于这个主题的现有问题,但还没有找到解决这个问题的方法。偶尔在我尝试过的变体中,我收到了“对象引用未保存的瞬态实例”错误。

1 个答案:

答案 0 :(得分:0)

非常基本! (希望这将有助于其他新手学到一些基本的东西)

问题是第二次使用站点代码时,它只是一个包含重复信息的SiteCode对象。 Hibernate尝试插入是作为新记录。

为使更新正确发生,SiteCode需要成为托管对象,即需要从数据库加载。

用这个替换第二个交易,问题就消失了:

session.beginTransaction();
SiteCodes sc4 = (SiteCodes) session.bySimpleNaturalId(SiteCodes.class).load(sc2.getSiteCode());
Networks nw2 = new Networks(789);
nw2.getSiteCodes().add(sc3);
nw2.getSiteCodes().add(sc4); // Same as sc2
session.merge(nw2);
session.getTransaction().commit();

感谢我的同事指出了这一点。