我正在尝试更新包含另一个类类型的字段的实体。
这是我的实体:
@Entity
public class Owner {
@Id
@GeneratedValue
private int id;
@Column(name = "first_name")
@NotNull(message="{NotNull}")
@Size(min=2,max=15,message="{Size}")
private String firstName;
@NotNull(message="{NotNull}")
@Size(min=2,max=15,message="{Size}")
@Column(name = "last_name")
private String lastName;
@Valid
@OneToOne(cascade = CascadeType.ALL)
private Phone phone;
@Valid
@OneToOne(cascade = CascadeType.ALL)
private Pet pet;
从这个角度来看:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1"></meta>
<title>Owner details</title>
</head>
<body>
<div id="owner">
<form th:action="@{|/ownerList/${owner.id}.do|}"
th:object="${owner}" method="post">
<table>
<tr>
<td>Id:</td>
<td><input type="text" th:field="*{id}" /></td>
<td th:if="${#fields.hasErrors('id')}" th:errors="*{id}">fieldError</td>
</tr>
<tr>
<td>First name</td>
<td><input type="text" th:field="*{firstName}" /></td>
<td th:if="${#fields.hasErrors('firstName')}"
th:errors="*{firstName}">fieldError</td>
</tr>
<tr>
<td>Last name</td>
<td><input type="text" th:field="*{lastName}" /></td>
<td th:if="${#fields.hasErrors('lastName')}"
th:errors="*{lastName}">fieldError</td>
</tr>
<tr>
<td>Phone</td>
<td><input type="text" th:field="*{phone.number}" /></td>
<td th:if="${#fields.hasErrors('phone.number')}"
th:errors="*{phones[0].number}">fieldError</td>
</tr>
<tr>
<td>Pet</td>
<td><input type="text" th:field="*{pet.petName}" /></td>
<td th:if="${#fields.hasErrors('pet.petName')}"
th:errors="*{pet.petName}">fieldError</td>
</tr>
<tr>
<td><input type="submit" value="update" name="action" /></td>
<td><input type="submit" value="delete" name="action" /></td>
</tr>
</table>
</form>
<a href="/ownerList">Back</a>
</div>
</body>
</html>
我正在使用此控制器:
@RequestMapping(value = "/ownerList/{id}.do")
public String ownerDetailsDo(@ModelAttribute(value = "owner") Owner owner, BindingResult result,
@RequestParam(value = "action") String action, Model model) {
switch (action) {
case "update":
ObjectBinder.bind(owner);
ownerService.update(owner);
return "ownerDetail";
case "delete":
ownerService.remove(owner.getId());
model.addAttribute("ownerList", ownerService.getAll());
return "ownerList";
}
model.addAttribute("owner", owner);
return "ownerDetail";
}
所以我试图更新所有者的对象,但是在.merge之后的数据库内部,我可以找到具有新ID的新实体,例如Phone。
举例来说,我有:
所有者:
名:XYZ
姓氏:BBB
宠物:BOB
电话:1234
当我尝试更新手机时,说“ 2222”,那么在数据库中我可以找到两个记录
一个是“ 1234”,第二个是“ 2222”,我想用“ 2222”替换旧的“ 1234”。
最佳答案
如果要删除未由任何所有者引用的电话,则需要添加@OrphanRemoval。
关系中的孤立孤儿当目标实体一对一或
一对多关系从关系中删除,通常是
希望将删除操作级联到目标实体。这样
目标实体被视为“孤儿”,而orphanRemoval
属性可用于指定孤立实体应为
删除。例如,如果一个订单有很多订单项,其中有一个
已从订单中删除,则已删除的订单项被视为
孤儿。如果orphanRemoval设置为true,则订单项实体将为
从订单中删除订单项后删除。
@OneToMany和@oneToOne中的orphanRemoval属性采用
布尔值,默认为false。
以下示例将删除操作级联到
从关系中删除的孤立客户实体:
@OneToMany(mappedBy =“ customer”,orphanRemoval =“ true”)公共
列出getOrders(){...}
@Entity
public class Owner {
@Id
@GeneratedValue
private int id;
@Column(name = "first_name")
@NotNull(message="{NotNull}")
@Size(min=2,max=15,message="{Size}")
private String firstName;
@NotNull(message="{NotNull}")
@Size(min=2,max=15,message="{Size}")
@Column(name = "last_name")
private String lastName;
@Valid
@OneToOne(cascade = CascadeType.ALL, orphanRemoval="true")
private Phone phone;
@Valid
@OneToOne(cascade = CascadeType.ALL, orphanRemoval="true")
private Pet pet;
如果您这样做:
owner.set(new Phone(2222));
entityManager.merge(owner));
// update the owner phone
owner.set(new Phone(77777));
//the phone(2222) will be deleted
entityManager.merge(owner));