在Spring中保存实体时,引用请求体中具有列的子实体。

huangapple go评论89阅读模式
英文:

Save entity in spring referencing child entity with a column in request body

问题

我有3个实体:User(用户)、Office(办公室)和Role(角色)。Role和Office已经存在于数据库中。

在SQL中,User实体使用其id引用Office,并使用其名称引用Role。SQL中的记录示例:

Role表
1 | USER

Office表
1 | Office 1

User表
John | Doe | john.doe@mail.com | Password123 | 1 | USER

对于User表
1 -> 引用Office
USER -> 引用Role

Role实体:

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "t_role")
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "name")
    private String name;
}

Office实体:

@Data
@Entity
@Table(name = "t_office")
public class Office {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "name")
    private String name;
}

User实体:

@Data
@Entity
@Builder
@Table(name = "t_user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email")
    private String email;

    @Column(name = "password")
    private String password;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name="role", referencedColumnName="name")
    private Role role;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "office_id", referencedColumnName="id")
    private Office office;
}

问题是:如何在不在请求体中指定所有Office和Role对象的情况下保存User?只需使用Office的id和Role的名称?也许需要使用DTO或Deserializer?

提前感谢。

我需要一个请求体如下:

{
  "firstName": "John",
  "lastName": "Doe",
  "email": "john.doe@mail.com",
  "password": "Password123",
  "officeId": 1,
  "role": "USER"
}

而不是一个请求体如下:

{
  "firstName": "John",
  "lastName": "Doe",
  "email": "john.doe@mail.com",
  "password": "Password123",
  "office": {
    "id": 1,
    "name": "Office 1"
  },
  "role": {
    "id": 1,
    "name": "USER"
  }
}
英文:

I have 3 entities: User, Office and Role. The Role and Office already exist in database.

In SQL the User entity references Office with its id and references Role with its name. Example of a record in SQL:

Role table:
1 | USER

Office table:
1 | Office 1

User table:
John | Doe | john.doe@mail.com | Password123 | 1 | USER

For user table:
1 -> reference to Office
USER -> reference to Role

Role entity:

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "t_role")
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "name")
    private String name;
}

Office entity:

@Data
@Entity
@Table(name = "t_office")
public class Office {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "name")
    private String name;
}

User entity:

@Data
@Entity
@Builder
@Table(name = "t_user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email")
    private String email;

    @Column(name = "password")
    private String password;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name="role", referencedColumnName="name")
    private Role role;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "office_id", referencedColumnName="id")
    private Office office;
}

The question is: How can I achieve saving a User without specifying all the Office and Role object in request body, but just the id for Office and name for Role ? Maybe it is needed to use a DTO or a Deserializer ?
Thanks in advance.

I need a request body like this:

{
  "firstName": "John",
  "lastName": "Doe",
  "email": "john.doe@mail.com",
  "password": "Password123",
  "officeId": 1,
  "role": "USER"
}

Instead of a request body like this:

{
  "firstName": "John",
  "lastName": "Doe",
  "email": "john.doe@mail.com",
  "password": "Password123",
  "office": {
    "id": 1,
    "name": "Office 1"
  },
  "role": {
    "id": 1,
    "name": "USER"
  }
}

答案1

得分: 2

是的,您需要使用DTO类来处理请求体部分。

public class UserDTO {
    private String firstName;

    private String lastName;

    private String email;

    private String password;

    private String role;

    private Integer officeId;
}

然后从数据库中获取办公室和角色的数据,并将数据设置到用户对象中,然后保存。例如:

User user = convertUserDTOtoUser(userDTO);
Optional<Office> office = officeRepository.findById(userDTO.getOfficeId());
Role role = roleRepository.findByName(userDTO.getRole());
user.setOffice(office);
user.setRole(role);
userRepository.save(user);

请注意,这是Java代码示例,用于处理请求体部分并与数据库交互。

英文:

Yes, you need to use a DTO class for the request body

public class UserDTO {
    private String firstName;

    private String lastName;

    private String email;

    private String password;

    private String role;

    private Integer officeId;
}

and fetch the data from the database for office and role from database and set the data in the user and then save. Ex:

User user = convertUserDTOtoUser(userDTO);
Optional&lt;Office&gt; office = officeRepository.findById(userDTO.getOfficeId());
Role role = roleRepository.findByName(userDTO.getRole());
user.setOffice(office);
user.setRole(role);
userRepository.save(user);

huangapple
  • 本文由 发表于 2020年8月2日 15:00:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/63213266.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定