我正在尝试更新包含另一个类类型的字段的实体。

这是我的实体:

@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));

10-06 05:34
查看更多