2014-01-22 148 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