I have a question to ask:
I have to tables user and user_login joined OneToOne by user.id -> user_login.user_id.
The issue is when I do .updateObject(user) I get 2 queries executed:
Hibernate: insert into User (created, modified, email, first_name,
last_name) values (?, ?, ?, ?, ?) Hibernate: insert into user_login
(created, modified, password, user_id) values (?, ?, ?, ?) [2012-08-15
12:15:04,192] [ERROR] [http-bio-8080-exec-1] SqlExceptionHelper [144]:
Column ‘user_id’ cannot be null
and looks like there is no reference between 2 objects. If into the Entity User, method setUserLogin I add line
userLogin.setUser(this); its working but I dont find this way elegant honestly. Is there anything I missed in entity configuration
maybe that does not do that automatically ?
Thank you
Here are my Entities
@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 File:
<%@ 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>
Spring Controller:
@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);
}
}
As usual, bidirectional relationships do have owning side. Owning side of relationship is attribute that is referenced by mappedBy. In your case attribute
userinUserLoginentity is the owning side.When relationship is persisted to the database, only owning side is consulted. This means, that you have to set value for
userattribute to be able to persist. To keep also entity graph in memory consistent both sides of the relationship should be set.In JPA 2.0 specification this is told with following words: