2014-01-22 107 views
0

我正在开发一个使用Spring MVC 3和Hibernate的应用程序。我有2类用户和TenancyDetails与父母和孩子的关系。在编辑细节功能中,我们可以编辑User类的详细信息并动态添加classTenancyDetails项并保存更改。我正在使用hibernate saveorupdate()方法,而hibernate正在为类User创建一个新记录,当它应该更新现有记录时。这是我的代码。Hibernate saveorupdate或合并保存/更新一对多关系对象

模型类:

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

} 

控制器:

@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方法:

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()); 
    } 

我还设置两个类如在MySQL AUTO_INCREMENT字段的ID的字段。 是否存在一对多映射或我用过的@GeneratedValue的问题?或者它与saveorupdate()方法有关吗?我应该在这种情况下使用merge()吗?在saveorupdate()语句之前,现有userId的值将被正确打印出来!

有人能让我知道我要去哪里吗?提前致谢。

+0

尝试合并()saveorupdate的instate()方法也读http://stackoverflow.com/questions/170962/nhibernate-difference-between-session -merge-and-session-saveorupdate –

+0

显示你的用户类。 –

+0

谢谢你ashish! – meenakshi

回答

1

我不知道,在渲染表单时如何将user对象放入您的Model中,最终来到您的POST方法"/Profile/{userId}"。您的user对象的id变为0。这就是为什么saveOrUpdate方法再次保存您的user。为了验证它,你可以在下方添加行,再进saveProfileDetails方法:

user.setUserId(userId); 

而且你的问题将得到解决。

您也可以通过在您的"/Profile/{userId}"GETPOST方法的拥有控制器之前加上@SessionAttributes("user")来解决此问题。

参见:

+0

非常感谢您的回复!随着使用merge()解决了问题:) – meenakshi