最近,当我在播放2.2.1 JPA(1.3.0.final)和 Hibernate(4.2.6.final) >框架,我得到了错误:
java.lang.IllegalStateException:存储实体时发生错误[xxx]实体副本[xxx]已分配给其他实体[yyy]
互联网上现有的解决方案都没有解决我的问题。
现在,让我解释一下这个故事。
我有三个实体,所有者,框和项目。
假设:
实体类:
/ *为简单起见,省略了其他字段,getter和setter * /
简化的所有者类定义
@Entity
@Table(name = "OWNER")
public class Owner implements Serializable{
@Id
@Column(name="ID")
public String uuid = UUID.randomUUID().toString();
@Override
public int hashCode() {
int result = 1;
char[] charArray = this.uuid.toCharArray();
int n = charArray.length;
int powbase = (int) Math.pow(31, n - 1);
for(int i = 0; i < n; i++){
if ( i != 0){
powbase = powbase / 31;
}
result += (int)charArray[i] * powbase;
}
return result;
}
@Override
public boolean equals(Object obj) {
if(obj == null){
return false;
}
if(!(obj instanceof Item)){
return false;
}
Item other = (Item)obj;
//Box other = (Box)obj;
//Owner other = (Owner)obj;
if(!other.uuid.equals(this.uuid)){
return false;
}
return true;
}
}
Item和Box的hashCode()和equals()的实现类似于Owner。为了论证,我们省略这些。
简化的Item类定义
@Entity
@Table(name = "ITEM")
public class Item implements Serializable{
@Id
@Column(name="ID")
public String uuid = UUID.randomUUID().toString();
/* single-directional mapping*/
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, optional = false)
@JoinColumn(name = "O_ID")
public Owner owner;
/* bi-directional mapping*/
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH })
@JoinColumn(name = "B_ID")
public Box box;
}
简化的Box类定义。
@Entity
@Table(name = "BOX")
public class Box implements Serializable {
@Id
@Column(name="ID")
public String uuid = UUID.randomUUID().toString();
/* single-directional mapping*/
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, optional = false)
@JoinColumn(name = "O_ID")
public Owner owner;
/* bi-directional mapping*/
@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REFRESH,
CascadeType.MERGE, CascadeType.REMOVE }, fetch = FetchType.EAGER, mappedBy = "box")
public Set<Item> items = new HashSet<Item>();
}
业务逻辑如下所示:
public class Test {
public static void main(String[] args) {
Owner owner = new Owner();
JPA.em().persist(owner);
Box box = new Box();
box.owner = owner;
JPA.em().persist(box);
Item boxItem = new Item();
boxItem.owner = owner;
boxItem.box = box;
box.items.add(boxItem);
JPA.em().persist(boxItem);
Item nonBoxItem = new Item();
nonBoxItem.owner = owner;
JPA.em().persist(nonBoxItem);
/* in the future, put the 'nonBoxItem' into a box*/
Item itemToUpdate = JPA.em().find(Item.class, nonBoxItem.uuid);
itemToUpdate.box = box;
box.items.add(itemToUpdate);
JPA.em().merge(itemToUpdate); /* error occurred here*/
}
}
有没有人有任何想法解决这个问题?
感谢。
答案 0 :(得分:0)
我遇到了同样的问题。通过添加对我有用的链接https://stackoverflow.com/questions/17634230/hibernate-an-entity-copy-was-already-assigned-to-a-different-entity的依赖来解决
<dependency>
<groupId>com.intersult</groupId>
<artifactId>jpa-fix</artifactId>
<version>1.1</version>
干杯!