我有一个父实体维护一个有序的项目列表:
@Entity
public class ActionList {
private String id;
private String actionId;
private String name;
private List<ActionItem> items = new ArrayList<ActionItem>();
@Id
public String getId() {
return this.id;
}
public void setId(final String id) {
this.id = id;
}
@Column(nullable = false)
public String getActionId() {
return this.actionId;
}
public void setActionId(final String actionId) {
this.actionId = actionId;
}
@Column(nullable = false)
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "actionlist")
@OrderColumn(name = "position")
public List<ActionItem> getItems() {
return this.items;
}
public void setItems(final List<ActionItem> items) {
this.items = items;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof ActionList)) {
return false;
}
final ActionList other = (ActionList) obj;
return getActionId().equals(other.getActionId());
}
@Override
public int hashCode() {
return Objects.hash(getActionId());
}
}
这是项目的类:
@Entity
public class ActionItem {
private String id;
private ActionList actionList;
private int position = 0;
private String name;
@Id
public String getId() {
return this.id;
}
public void setId(final String id) {
this.id = id;
}
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "actionList_id", nullable = false)
public ActionList getActionList() {
return this.actionList;
}
public void setActionList(final ActionList actionList) {
this.actionList = actionList;
}
@Column(name = "position")
public Integer getPosition() {
return this.position;
}
public void setPosition(final Integer position) {
this.position = position;
}
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof ActionItem)) {
return false;
}
final ActionItem other = (ActionItem) obj;
if (StringUtils.isNotEmpty(getId()) && StringUtils.isNotEmpty(other.getId())) {
return getId().equals(other.getId());
}
return getActionList().equals(other.getActionList()) && getPosition().equals(other.getPosition());
}
@Override
public int hashCode() {
if (StringUtils.isNotEmpty(getId())) {
return Objects.hash(this.getId());
} else {
return Objects.hash(this.getActionList(), this.getPosition());
}
}
}
我的问题是,当我在添加一些项目后从项目集合中删除时,第一个元素也会被删除...
以下是我一直在使用的测试:
@Test
public void testAddAndDelete() {
final ActionList actionList = new ActionList();
actionList.setActionId("testActionList");
actionList.setName("testActionList");
eManager.persist(actionList);
final String actionListId = actionList.getId();
ActionList actionListFromDB = eManager.getById("ActionList", actionListId);
ActionItem itemToRemove = null;
for (int f = 0; f < 5; f++) {
final ActionItem newItem = new ActionItem();
newItem.setActionList(actionListFromDB);
newStep.setName("itemname" + f);
actionListFromDB.getItems().add(newItem);
eManager.persist(newItem);
eManager.merge(actionListFromDB);
if (f == 3) {
itemToRemove = newItem;
}
}
eManager.commit();
actionListFromDB = eManager.getById("ActionList", actionListId);
actionListFromDB.getItems().remove(itemToRemove);
eManager.merge(actionListFromDB);
eManager.commit();
}
如果我在删除之前查看数据库,我会在ActionItem表中查看:
ID ACTIONLIST_ID POSITION NAME
fbb3ddae-f8b7-11e4-8d6c-b9778e934988 f51846ca-f8b7-11e4-8d6c-1ba6d68e492d 0 itemname0
fbb56453-f8b7-11e4-8d6c-dfaa3c092bd0 f51846ca-f8b7-11e4-8d6c-1ba6d68e492d 1 itemname1
fbb60098-f8b7-11e4-8d6c-154d56d0c562 f51846ca-f8b7-11e4-8d6c-1ba6d68e492d 2 itemname2
fbb675cd-f8b7-11e4-8d6c-21a3cc2b3c81 f51846ca-f8b7-11e4-8d6c-1ba6d68e492d 3 itemname3
fbb71212-f8b7-11e4-8d6c-8f7c1ecfd151 f51846ca-f8b7-11e4-8d6c-1ba6d68e492d 4 itemname4
然后我检查了ActionList对象,它的集合在删除后肯定有4个项目(这是正确的),它们的位置属性是不正常的(我希望自从中间删除)。
但是一旦我让删除后的提交通过,表格最终会显示:
ID ACTIONLIST_ID POSITION NAME
fbb56453-f8b7-11e4-8d6c-dfaa3c092bd0 f51846ca-f8b7-11e4-8d6c-1ba6d68e492d 1 itemname1
fbb60098-f8b7-11e4-8d6c-154d56d0c562 f51846ca-f8b7-11e4-8d6c-1ba6d68e492d 2 itemname2
fbb71212-f8b7-11e4-8d6c-8f7c1ecfd151 f51846ca-f8b7-11e4-8d6c-1ba6d68e492d 3 itemname4
因此,删除了正确的元素,但是:
我知道现在支持带有mappedBy的@OrderColumn,所以我不认为这是 - 我怀疑hashCode()有些可疑,但事实上该集合在ActionList对象中看起来没问题坚持有点奇怪......
我在日志中没有从Hibernate获得任何异常。
答案 0 :(得分:0)
与以往一样,是一个映射问题。
将ActionItem上的映射更改为:
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
@JoinColumn(name = "actionList_id", nullable = false)
public ActionList getActionList() {
return this.actionList;
}
修正了它。