我有两个实体类:
- 用户:用户的凭据。
- UserInfo : 用户的anagraphic infos。
和一个DAO:
- UserDAO : 类 User 的 Dao。
它们通过主键作为外键与 OneToOne 关系链接。所以 User.id 是 User 和 UserInfo 的主键。
数据获取运行良好,但问题是:当我使用 userDAO 保存用户时,UserInfo 不知道它必须保存的主键。
如何告诉 UserInfo 等待用户被保存以了解其共享主键?
我得到了这个例外
Request processing failed; nested exception is org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [com.marciani.sample.entity.user.model.UserInfo.user]
先感谢您!
这是代码:
用户
@Entity
@Table(name = "users")
public class User implements Serializable {
private static final long serialVersionUID = -7351729135012380019L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id", nullable = false, unique = true)
private Integer id;
@Column(name = "username", nullable = false, unique = true, length = 25)
private String username;
@Column(name = "password", nullable = false, unique = false, length = 25)
private String password;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "role_id", nullable = false)
@ForeignKey(name = "fk_user_role")
private Role role;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
private UserInfo userInfo;
public User(String username, String password, Role role, UserInfo userInfo) {
this.username = username;
this.password = password;
this.role = role;
this.userInfo = userInfo;
}
public User() {}
//Getters/Setters ...
}
用户信息
@Entity
@Table(name = "users_info")
public class UserInfo implements Serializable {
private static final long serialVersionUID = 3977944889257599040L;
@Id
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign", parameters={@Parameter(name="property", value="user")})
private Integer userId;
@Column(name = "firstname", nullable = false, unique = false, length = 25)
private String firstname;
@Column(name = "lastname", nullable = false, unique = false, length = 25)
private String lastname;
@Column(name = "email", nullable = false, unique = false, length = 50)
private String email;
@OneToOne
@MapsId
private User user;
public UserInfo(String firstname, String lastname, String email) {
this.firstname = firstname;
this.lastname = lastname;
this.email = email;
}
public UserInfo() {}
//Getters/Setters
}
用户服务
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserDAO userDAO;
@Override
@Transactional(readOnly = false)
public void saveUser(User user) {
userDAO.saveUser(user);
}
@Override
@Transactional(readOnly = false)
public void deleteUser(String username) {
User user = findByUsername(username);
userDAO.deleteUser(user);
}
@Override
@Transactional(readOnly = true)
public User findByUsername(String username) {
Criterion criterion = Restrictions.eq("username", username);
List<User> list = userDAO.find(criterion);
return list.get(0);
}
@Override
@Transactional(readOnly = true)
public User getUser(String username, String password) {
Criterion criterion = Restrictions.conjunction()
.add(Restrictions.eq("username", username))
.add(Restrictions.eq("password", password));
List<User> list = userDAO.find(criterion);
if (list.size() > 0) {
return list.get(0);
} else {
return null;
}
}
@Override
@Transactional(readOnly = true)
public List<User> findAll() {
return userDAO.findAll();
}
}
用户DAO
@Repository
public class UserDAOImpl implements UserDAO {
@Autowired
public SessionFactory sessionFactory;
public Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
@Override
public void saveUser(User user) {
getCurrentSession().saveOrUpdate(user);;
}
@Override
public void deleteUser(User user) {
getCurrentSession().delete(user);
}
@Override
public List<User> find(Criterion criterion) {
Criteria criteria = getCurrentSession().createCriteria(User.class);
criteria.add(criterion);
return criteria.list();
}
@Override
public List<User> findAll() {
Criteria criteria = getCurrentSession().createCriteria(User.class);
return criteria.list();
}
}