Spring Boot JPA一对一映射

问题描述

我有两个实体,如下所示:

用户实体

@Entity
@Table(name = "user")
@Getter
@Setter
@NoArgsConstructor
public class User {

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

    @OnetoOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "id")
    private UserDetails userDetails;

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

    public User(final String description) {
        this.description = description;
    }
}

用户详细信息实体

@Entity
@Table(name = "user_details")
@Getter
@Setter
@NoArgsConstructor
public class UserDetails {

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

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

    @OnetoOne(mappedBy = "userDetails")
    private User user;

    public UserDetails(final String description) {
        this.description = description;
    }
}

我的飞行脚本如下:

CREATE TABLE `user` (
`id` int PRIMARY KEY AUTO_INCREMENT,`description` varchar(255)
);

CREATE TABLE `user_details` (
`id` int PRIMARY KEY AUTO_INCREMENT,`user_id` int,`description` varchar(255)
);

ALTER TABLE `user_details` ADD FOREIGN KEY (`user_id`) REFERENCES `user` (`id`);

当我启动应用程序时,表格可以正常创建。我希望用户表是父表,而user_details表是子表,它可以很好地创建。但是,当我在数据库中插入用户时,user_details表中的user_id列将存储为null。下面是我的控制器。

UserController

@RestController
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("/users/{id}")
    public ResponseEntity < User > getUser(@PathVariable("id") Long id) {

        User user = userRepository.getone(id);
        return new ResponseEntity < > (user,HttpStatus.OK);
    }

    @PostMapping("/users")
    public ResponseEntity < User > saveUser(@Valid @RequestBody User user) {

        User userSaved = userRepository.save(user);
        return new ResponseEntity < > (userSaved,HttpStatus.OK);
    }
}

用户存储库

@Repository
public interface UserRepository extends JpaRepository<User,Long> {

}

为什么user_details表中的user_id列存储为null?

下面是我的卷发:

curl - X POST\
http: //localhost:5000/users \
    -H 'Cache-Control: no-cache'\ -
    H 'Content-Type: application/json'\ -
    H 'Postman-Token: 22a98f2b-d3cc-4127-b3ad-35f28c916fa4'\ -
    d '{
"description": "Some user","userDetails": {
    "description": "Some user details"
    }
}

解决方法

您的映射不合适。关系的所有者为keys。因此,关系应该存在于UserDetails实体中。

找到下面添加的映射。

用户实体

UserDetails

UserDetails实体

@Entity
@Table(name = "user")
@Getter
@Setter
@NoArgsConstructor
public class User {

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

    @OneToOne(mappedBy = "user",cascade = CascadeType.ALL)
    private UserDetails userDetails;

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

    public User(final String description) {
        this.description = description;
    }
}
,

在某些情况下,您想保留实体之间共有的一些详细信息。例如,您有一个表DepartmentUser和其他User_address,又有一个表ManagementUser,并且在此表中,您还想映射用户地址,因为两种类型的用户都将拥有地址,在这种情况下您可能想使用关联!但是Hinbernate确实有一个很棒的功能,称为Embedding entity。您可以将用户地址简单地嵌入每个需要放置用户地址的实体中。

这可以通过这种方式完成。

@Entity
class DepartmentUser{
   @Id
   @GeneratedValues(strategy = GenerationType.IDENTITY)
   private Long id;
   private String name;
   private String eamil;
   @Embedded
   private UserAddress address;

//Standard setters and getters
}

另一个表的用户地址

@Embaddable
class UserAddress{
  private String state;
  private int zip;
  private String country;

//Standard setters and Getters
}

这只会在您的部门用户数据库中附加UserAddress中的列,这也会带来良好的性能。