Hibernate 一对一更新创建新的子对象而不是更新现有的

Posted

技术标签:

【中文标题】Hibernate 一对一更新创建新的子对象而不是更新现有的【英文标题】:Hibernate update one-to-one creates new child object instead of updating the existing one 【发布时间】:2017-02-21 11:48:57 【问题描述】:

在我的 spring mvc 应用程序中,我在数据库中有医生和用户表。每个医生都有一个用户。问题是当我尝试更新医生时,属于医生的用户没有被更新。相反,我在我的数据库中看到了一个属于更新医生的新用户。

这是我的 Doctor.java 实体:

@Entity
@Table(name="doctor")
public class Doctor 

    @Id
    @Column(name="id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;


    @Column(name="name")
    private String name;


    @Column(name="tel")
    private String tel;

    @Column(name="email")
    @Email
    private String email;

    private transient String ConfirmPassword;

    @OneToOne(fetch = FetchType.EAGER,  cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id")
    private User user;

    //getter and setters....

这是我的 User.java 实体

@Entity
@Table(name="user")
public class User 

    @Id
    @Column(name="id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;


    @Column(name="username")
    private String username;


    @Column(name="password")
    private String password;


    //getters and setters...

这是我的表格:

<form:form action="save" modelAttribute="doctor" method="post">

        <form:errors path="name"></form:errors>
        <form:input path="name" placeholder="Doktor İsmi" class="form-control" />

        <form:input path="user.username" placeholder="Kullanıcı Adı" class="form-control" />

        <form:input type="email" path="email" placeholder="Email" class="form-control" />

        <form:input path="tel" placeholder="Telefon" class="form-control" />

        <form:input type="password" path="user.password" placeholder="Şifre" class="form-control" />

        <form:hidden path="id" />/>
        <input type="submit" value="Doktor Kaydet" />
    </form:form>

这里是控制器保存方法:

@PostMapping(value="/save")
    public String save(@Valid Doctor dr, @Valid User usr, BindingResult bindingResult)

        doctorValidator.validate(dr, bindingResult);
        if (bindingResult.hasErrors()) 
            return "admin/doctor-form";
        
        else
            dr.getUser().setIs_doctor(1);
            doctorService.save(dr);
            return "redirect:list";
        
    

最后是DoctorDAO。保存方法,我没有给用户额外的保存操作,因为它应该通过医生保存。

public void save(Doctor dr) 
        Session s = sessionFactory.getCurrentSession();
        s.saveOrUpdate("doctor", dr);

    

我尝试阅读参考资料,我已经阅读了示例等等。我是 Hibernate 和 JEE 平台的初学者。两天没找到解决办法。

谢谢,

【问题讨论】:

你能告诉我们保存方法本身吗? 我现在已经包含了这些方法 更新期间,医生和用户是否设置了id? 不,我直接更新如上 如何在没有设置实体 ID 的情况下执行更新? 【参考方案1】:

我会这样做:

public void save(Doctor dr) 
    Session s = sessionFactory.getCurrentSession();
    Doctor managedDr = s.merge(dr);
    managedDr.getUser().setIs_doctor(1);
    s.saveOrUpdate("doctor", managedDr);


现在,在合并期间,将获取用户实体,当您执行 saveOrUpdate 时,它​​应该更新用户而不是插入,因为 id 将在那里。

【讨论】:

非常感谢,我怎么从来没见过这个 不用担心。很高兴我能帮上忙

以上是关于Hibernate 一对一更新创建新的子对象而不是更新现有的的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate使用注意事项

Coredata 合并关系而不是覆盖它

Hibernate session.update插入行而不是更新行

关联映射 ---- Hibernate之多对多关系

在插入新的子对象时,父子对象传递与多级的一对多关系。 IOS核心数据

hibernate一对多单向关联时更新问题