开发者社区> 问答> 正文

休眠-1:N-父级在保存子级后被复制

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

预期:

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

错误:

CascadeType.ALL导致父级重复,但是尝试删除它以使用其他类型抛出: java.sql.SQLIntegrityConstraintViolationException:列“ user_id”不能为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(这是用于存储子用户名的方法,该方法复制了父用户user)

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

用户名服务

usernameDAO.save(username);

展开
收起
几许相思几点泪 2019-12-29 19:46:19 899 0
1 条回答
写回答
取消 提交回答
  • 我相信您在对象Username中分配对象User的方式不正确。如果您正在执行以下操作:

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

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

    如果您不想为新建一个条目user,则必须从数据库中加载该实体,因此您应该在服务类中添加一个新方法,User该方法将为您返回一个给定用户ID的用户。

    例如:

    User user = userService.getUser(10);
    
    Username username = new Username();
    username.set(user);
    
    

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

    2019-12-29 19:46:45
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载