[英]Hibernate saveorupdate or merge for saving/updating one-to-many relationship objects
I am developing an application using Spring MVC 3 and Hibernate. 我正在使用Spring MVC 3和Hibernate开发应用程序。 I have 2 classes User and TenancyDetails with parent-child relationship.
我有2个具有父子关系的User和TenancyDetails类。 In the edit details functionality, we can edit the details of class User and dynamically add classTenancyDetails items and save the changes.
在编辑详细信息功能中,我们可以编辑User类的详细信息,并动态添加classTenancyDetails项目并保存更改。 I am using hibernate saveorupdate() method for this and hibernate is creating a new record for class User when it should be updating the existing record.
我为此使用hibernate saveorupdate()方法,并且hibernate应该在更新现有记录时为User类创建一条新记录。 Here is my code.
这是我的代码。
Model classes: 模型类别:
@Entity
@Table(name="tenancydetails")
public class TenancyDetails {
@Column(name="tenancyID")
@Id
@GeneratedValue
private int tenancyId;
@Column(name="landlordName")
@NotNull
private String landlordName;
@Column(name="landLordEmail")
@NotNull
private String landlordEmail;
@Column(name="fromDate")
@NotNull
private Date fromDate;
@Column(name="toDate")
@NotNull
private Date toDate;
@Column(name="location")
@NotNull
private String location;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="userId", nullable=false)
private User user;
@Transient
protected Object[] jdoDetachedState;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public int getTenancyId() {
return tenancyId;
}
public void setTenancyId(int tenancyId) {
this.tenancyId = tenancyId;
}
public String getLandlordName() {
return landlordName;
}
public void setLandlordName(String landlordName) {
this.landlordName = landlordName;
}
public String getLandlordEmail() {
return landlordEmail;
}
public void setLandlordEmail(String landlordEmail) {
this.landlordEmail = landlordEmail;
}
public Date getFromDate() {
return fromDate;
}
public void setFromDate(Date fromDate) {
this.fromDate = fromDate;
}
public Date getToDate() {
return toDate;
}
public void setToDate(Date toDate) {
this.toDate = toDate;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
@Entity
@Table(name="User")
public class User {
@Column(name="userId")
@Id
private int userId;
@Column(name="name")
private String name;
@Column(name="emailId")
@NotEmpty(message = "Please enter your email id")
@Size(max = 50, message = "Email id can only be upto 50 characters long")
private String emailId;
@Column(name="password")
@NotEmpty(message = "Please enter your password")
@Size(max = 20, message = "Password can only be upto 20 characters long")
private String password;
@OneToMany(cascade={CascadeType.ALL}, fetch = FetchType.EAGER)
@Cascade({org.hibernate.annotations.CascadeType.DELETE_ORPHAN,
org.hibernate.annotations.CascadeType.PERSIST,
org.hibernate.annotations.CascadeType.SAVE_UPDATE})
@JoinColumn(name="userId"/*, nullable=true*/)
@LazyCollection(LazyCollectionOption.FALSE)
private List<TenancyDetails> tenancyDetails = null;
public User(){
tenancyDetails = new AutoPopulatingList<TenancyDetails>(TenancyDetails.class);
}
public List<TenancyDetails> getTenancyDetails() {
return tenancyDetails;
}
public void addTenancyDetail(TenancyDetails tenancyDetail) {
if (!tenancyDetails.contains(tenancyDetail)) {
tenancyDetails.add(tenancyDetail);
}
}
public void setTenancyDetails(List<TenancyDetails> tenancyDetails) {
this.tenancyDetails = tenancyDetails;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Controller: 控制器:
@RequestMapping(value = "/Profile/{userId}", method = RequestMethod.POST)
public ModelAndView saveProfileDetails(@PathVariable int userId, Model model, HttpServletRequest request, HttpServletResponse response,
HttpSession session, ModelMap modelMap, @ModelAttribute("user") User user) {
System.out.println("am in save");
model.addAttribute("user", user);
System.out.println(user.getPassword());
System.out.println(user.getTenancyDetails().get(0).getUser().getUserId());
System.out.println(model.containsAttribute("user"));
tenantRatingService.saveProfileDetails(user);
return new ModelAndView("editProfile","user", user);
}
DAO method: DAO方法:
public void saveProfileDetails(User user){
System.out.println("inside the save profile method");
Session session = getSession();
Transaction transaction = session.beginTransaction();
System.out.println("before save: " + user.getPassword());
System.out.println("before save: " + user.getTenancyDetails().get(0).getUser().getUserId());
session.saveOrUpdate(user);
transaction.commit();
session.flush();
System.out.println(user.getPassword());
}
I have also set the id fields of both classes as AUTO_INCREMENT fields in mysql. 我也将这两个类的id字段设置为mysql中的AUTO_INCREMENT字段。 Is there a problem with the one to many mapping or the @GeneratedValue I have used?
我使用的一对多映射或@GeneratedValue是否存在问题? Or is it to do with the saveorupdate() method?
还是与saveorupdate()方法有关? Should I use merge() in this case?
在这种情况下,我应该使用merge()吗? Just before the saveorupdate() statement, the value of the existing userId is printed out correctly!
在saveorupdate()语句之前,已正确打印出现有userId的值!
Can someone please let me know where I am going wrong? 有人可以让我知道我要去哪里吗? Thanks in advance.
提前致谢。
I don't know, how you are putting user
object in your Model
while rendering the form, which eventually comes to your POST method of "/Profile/{userId}"
. 我不知道,您如何在呈现表单时将
user
对象放入Model
而表单最终出现在您的POST方法"/Profile/{userId}"
。 The id
of your user
object becoming 0
. user
对象的id
变为0
。 That's why saveOrUpdate
method saves your user
again. 这就是为什么
saveOrUpdate
方法再次保存您的user
的原因。 To verify it, you can add the line below, before going into saveProfileDetails
method: 要进行验证,可以在进入
saveProfileDetails
方法之前添加以下行:
user.setUserId(userId);
And your problem will be fixed. 您的问题将得到解决。
You can also fix this problem by putting @SessionAttributes("user")
, before the owning controller of your "/Profile/{userId}"
's GET
and POST
method. 您还可以通过将
@SessionAttributes("user")
放在"/Profile/{userId}"
的GET
和POST
方法的所有者控制器之前,来解决此问题。
See also: 也可以看看:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.