Java 更新包含对象字段的实体
我正在尝试更新包含其他类类型字段的实体 这就是我的实体:Java 更新包含对象字段的实体,java,hibernate,jpa,Java,Hibernate,Jpa,我正在尝试更新包含其他类类型字段的实体 这就是我的实体: @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;
@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>
所以我试图更新Owner的对象,但在.merge之后的数据库中,我可以找到新的实体,例如Phone,具有新Id
因此,举例来说,我有:
所有者:
名字:XYZ
姓氏:BBB
宠物:鲍勃
电话:1234
当我尝试更新手机时,比如说“2222”,然后在DB中我可以找到两条记录
一个是“1234”,第二个是“2222”,我想用“2222”替换旧的“1234”。发生这种情况是因为您正在使用电话号码作为您的
电话实体的@Id
。并且您不能更改实体的ID:您可以使用不同的ID创建一个新实体,或者findById(number)
现有实体并更新其他字段的值(但不能更改@ID
字段,因为这将再次创建一个新实体)
如果电话号码(“1234”或“2222”)是您所需要的全部,那么开始使用phone
类是没有意义的。您只需使用字符串
(如果您希望能够使用+XX XXX…格式或验证电话号码长度),甚至可以使用整数
如果您确实需要Phone
类,因为它有其他字段(如Phone.totalCallsMade
或类似字段),那么您的程序将按预期工作:不同的号码、不同的实体。如果您想在没有任何所有者引用的情况下删除手机,则需要添加@orniremove
当目标实体处于一对一或
一对多关系从关系中移除,通常是
希望将删除操作级联到目标实体。这样的
目标实体被视为“孤立实体”,孤立实体被删除
属性可用于指定应删除孤立实体
远离的。例如,如果订单有多个行项目,其中一个
如果从订单中删除,则删除的行项目将被视为
孤儿。如果将删除设置为true,则行项目实体将为
从订单中删除行项目时删除
@OneToMany和@oneToOne中的孤儿移除属性采用
布尔值,默认情况下为false
以下示例将删除操作级联到
从关系中删除孤立客户实体时:
@OneToMany(mappedBy=“customer”,orphan=“true”)公共
列出getOrders(){…}
如果你这样做:
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));
在您的控制器中,更新方法不知道必须为特定的所有者Id更新哪个电话号码。在更新您的电话号码之后,从Jsp将所有者Id值作为隐藏值传递,并将具有特定所有者Id的电话号码作为隐藏值传递给Jsp,以获取控制器中的值。
@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));