java - 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);
解决方案
我相信您在对象用户名中分配对象用户的方式不正确。如果你正在做这样的事情:
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 中的主键)相同,关键字也会创建一个新条目。
推荐阅读
- swift - 使用 macOS Big Sur 版本 11.1 时收到安装 Firestore pod 的错误消息
- html - 仅使用 CSS,如果 ID 存在,如何隐藏父子元素?
- javascript - 将来自 API 的错误显示到前端
- vuejs2 - 我的电子 Vuejs 有一个问题,无法从承诺中重新呈现数据更改
- python - 如何为另一个版本的 python 制作 pip install 东西
- reactjs - React Material Table:编辑在 detailPanel 中显示的隐藏行
- python-3.x - 重命名单个图 ia 5 个图的序列
- pandas - 从 ClickHouse 获取数据到 Pandas 数据帧时减少 RAM 消耗
- javascript - 多次调用自身的函数的javascript递归问题
- android - 如何发送多个 api 请求并在 RecyclerView 中显示结果?