2012-08-15 92 views
1

我有一個問題要問:休眠OneToOne使用Spring和JSP

我有表用戶和USER_LOGIN加入OneToOne通過user.id - > user_login.user_id。

的問題是,當我做.updateObject(用戶)我得到2個查詢執行:

休眠:?插入到用戶(創建,修改,電子郵件,FIRST_NAME, 姓氏)值(,, (?,?,?)?Hibernate:insert into user_login values(?,?,?,?)[2012-08-15 12:15:04,192] [錯誤] [http-生物-​​8080-exec-1] SqlExceptionHelper [144]: 列'user_id'不能爲空

看起來l ike在2個對象之間沒有引用。如果進入實體用戶,方法setUserLogin我添加行 userLogin.setUser(this);它的工作,但我沒有誠實地找到這種方式優雅。有沒有我在實體配置 錯過了,也許這不會自動執行?

謝謝

這裏是我的實體

@Entity 
@NamedQueries({ @NamedQuery(name = "user.list", query = "select u from User u") }) 
public class User implements java.io.Serializable { 

    @Column(name = "first_name", nullable = true) 
    private String firstName; 

    @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    @JoinColumn(name="user_id", nullable=false) 
    private UserLogin userLogin; 

    public String getFirstName() { 
     return firstName; 
    } 

    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
    } 


    public UserLogin getUserLogin() { 
     return userLogin; 
    } 

    public void setUserLogin(UserLogin userLogin) { 
     this.userLogin = userLogin; 
     //userLogin.setUser(this); THIS IS THE LINE THAT FIXES IT, BUT I DONT FIND THIS WAY ELEGANT 
    } 

} 


@Entity 
@Table(name="user_login") 
public class UserLogin implements java.io.Serializable { 

    @Column(name = "password", nullable = false) 
    private String password; 


    @OneToOne(optional = false, fetch = FetchType.LAZY) 
    private User user; 


    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    public User getUser() { 
     return user; 
    } 

    public void setUser(User user) { 
     this.user = user; 
    } 

} 

JSP文件:

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%> 
<html> 
<head> 
<title>Registration Page</title> 
</head> 
<body> 
    <form:form action="/test" commandName="user"> 
     <tr> 
      <td>User Name :</td> 
      <td><form:input path="firstName" /></td> 
     </tr> 
     <tr> 
      <td>Password :</td> 
      <td><form:input path="userLogin.password" /></td> 
     </tr> 
     <tr> 
      <td colspan="2"><input type="submit" value="Register"></td> 
     </tr> 
     </table> 
    </form:form> 
</body> 
</html> 

春控制器:

@Controller(value = "/") 
public class Test { 

    @Autowired 
    UserServiceImpl userServiceImpl; 

    @RequestMapping(method = RequestMethod.GET, value = "/test") 
    public void test(ModelMap model) { 

    model.addAttribute("user", new User()); 

    } 

    @RequestMapping(method = RequestMethod.POST, value = "/test") 
    public void test(User user) { 

    userServiceImpl.update(user);  

    } 
} 
+0

您的實體的代碼是否完整? – 2012-08-15 16:54:09

+0

是的,我只是沒有粘貼進口。當然我也會添加更多的字段 – Dima 2012-08-16 17:09:20

回答

2

像往常一樣,雙向關係確實有持有端。關係的所有方是由mappedBy引用的屬性。在你的案例屬性userUserLogin實體是擁有方。

當關系持續到數據庫時,僅查詢擁有方。這意味着,您必須爲user屬性設置值才能夠保留。爲了保持實體圖形在內存中的一致性,應該設置關係的雙方。

在JPA 2.0規範這種雜糅了下面的話:管理實體之間

雙向關係將基於關係的擁有方持有的引用被持久化 。它是 開發者有責任在內存中保留 在擁有方和保持相反方面與 互相保持一致,當他們改變。