首页 > 解决方案 > Hibernate - 1:N - 保存孩子时复制父母

问题描述

GitHub repo(如果需要)、Maven Web 项目(pom.xml)、资源目录下的 SQL 脚本。

我知道这是我的错,问题是我一整天都无法修复它,它可能很简单而且我的头脑中,也请忽略有关表名和列的关系,这是一个示例项目来显示问题。


预期的:

沿其父关系存储新子项(子项有一个列),而无需再次存储父项。


错误:

CascadeType.ALL导致父级重复,但尝试将其删除以使用其他类型会抛出: java.sql.SQLIntegrityConstraintViolationException: Column 'user_id' cannot be null

列 'user_id'是子表中存储父关系的列的名称。


我将跳过一些注释,这样就不会成为代码墙


用户实体

private Long id;
private String name;

@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = {
        CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH})
private List<Username> usernameList = new ArrayList<>();

用户名实体

private Long id;
private String username;

@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "user_id")
private User user;

同样,由于某种原因,使用CascadeType.All 以外的任何内容都会引发错误


UsernameDAO这是用于存储子用户名的方法,它与父用户名重复

Session session = factory.getCurrentSession();
session.save(username);

用户名服务

usernameDAO.save(username);

标签: javahibernatespring-mvcone-to-manycascade

解决方案


我相信您在对象用户名中分配对象用户的方式不正确。如果你正在做这样的事情:

User user = new User();
user.set(... // set your attributes

Username username = new Username();
username.set(user);

现在,如果您保存username,hibernate 将在数据库中创建一个条目,user因为您创建的方式user是使用new关键字,这将在数据库中创建一个新条目。

user如果您不想为User.

例如:

User user = userService.getUser(10);

Username username = new Username();
username.set(user);

现在,当您保存时username,这不会在表中创建新条目User。这就是休眠的工作方式。我们必须加载实体,然后对其进行操作并保存。new即使实体的 id(db 中的主键)相同,关键字也会创建一个新条目。


推荐阅读