java - 在不知道来自前端和 JSON 的数据库 ID 的情况下将子实体分配给父实体

标签 java json hibernate dto

我正在使用 spring 和 hibernate 开发一个 RESTFUL web 应用程序。我想创建一个新的 USER 实体,该实体与 ROLE 实体具有 ManyToOne 关系:

@Entity
@Table(name = "roles")
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;

    @Column(unique = true)
    private RoleEnum name;
}


@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;

    private String firstName;
    private String lastName;

    @ManyToOne
    private Role role;
}

在前端 html 和 ajax 中,我设置了除 ids(USER 的 id 和 ROLE 的 id)之外的所有字段,并将 json 字符串发送到后端。这是示例 json:

{
    "firstName": "john",
    "lastName": "becks",
    "role": {
         "name": "STUDENT"
     }
}

问题来了,我想将 STUDENT 角色分配给数据库中存在的这个新 USER,但我只知道它的名称而不是 id。我从 hibernate 中得到错误:

TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing

谁能帮忙解决这个问题?

提前致谢!

最佳答案

您的示例中缺少很多部分,但简单地说,hibernate 在其持久性上下文中没有关系中的 Role 实例。换句话说,它告诉您在保留用户之前先保留新角色。 Hibernate 很聪明,它跟踪从数据库中获取的对象并可以区分新实体和现有实体。

显然,这不是您想要做的,您想要使用现有角色,而不是创建新角色。

做到这一点的唯一方法是从数据库加载角色,使用名称找到它,并将检索到的角色添加到关系中。

像这样:

public User createUser(final String userFirstName, final String userLastName, final String roleName) {

    Role role = roleDao.findByName(roleName);

    if(role == null) {

        role = new Role(roleName);
        roleDao.save(role);
    }

    final User user = new User(userFirstName, userLastName);
    user.addRole(role);
    userDao.save(user);

    return user;
}

关于java - 在不知道来自前端和 JSON 的数据库 ID 的情况下将子实体分配给父实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57358833/

相关文章:

java - 强制执行刷新以获取新的主键 ID 来存储 EmbeddedId

java - 无法从有效的 URL 中读取 HTML 内容

java - 在 Selenium 中设置 Cookie 而不访问页面

java - Jackson 反序列化 JSON,跳过没有必填字段的对象?

python - 将 JSON 值转换为字符串

python - 检查键/值是否在 JSON 中

hibernate - 在 HQL 中连接多个表

java - 在 Android 上下载的视频只能从应用程序播放

c# - Json.Net "m³/h"反序列化为 "m�/h"

java - Hibernate异常: Unable to get the default Bean Validation factory with JRE 7