【问题标题】:ManyToOne gives null on two tables on create spring boot hiernate jpaManyToOne 在创建 spring boot hibernate jpa 的两个表上给出 null
【发布时间】:2021-02-09 13:47:15
【问题描述】:

例如,如果有表“用户”和“地址”,一个用户可以有 1 到多个地址,所以关系是一对多的。当我插入数据时,我将在同一个 json 中插入用户和地址列表。

问题是在创建与这两个相关的字段时为空。我找不到插入数据的正确方法,因此它会创建所有这些数据,然后还填充完成 onetomany 关系的字段。

我有两个相互关联的表,表“用户”和“地址”:

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

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

    @NotNull
    @Column(unique = true)
    private String user_name;

    @Column
    private String description;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
    protected Set<Address> addresses= new HashSet<>();
}

在另一张桌子上:

@Entity
@Table(name = "address")
@Data
public class Address{

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

    @ManyToOne
    @JoinColumn(name = "user_id")
    protected User user;

    private String description;
}

我做了一个发布请求来创建具有一些地址的新用户:

@PostMapping ("/user/create")
public ResponseEntity post(@RequestBody User user) {
    jpaRepository.save(user);
     // return
}

在一个帖子请求中,我发送了这个 json:

{
 
  "user_name": "example",
  "description": "this is a  user description",
  "comments": [
    {
      "description": "this is a address 1"
    },
    {
      "description": "this is a address 2"
    }
  ]
}

当我插入数据时,我得到“地址”表,“user_id”为空,数据已插入但关系不存在? 我在这里做错了什么?请帮忙!

更新: 我想过做这样的事情,但不知道如何称呼它:

public class User{
    
    ....
    
     public void addAddress(Address address) {
        address.setUser(this);
        addresses.add(address);
    }

}

【问题讨论】:

    标签: java spring-boot hibernate jpa spring-data-jpa


    【解决方案1】:

    你需要使用它来连接列(user) => @JoinColumn(name = "users_id",nullable = false)

    【讨论】:

    • 这只是给出了一个非空异常。还有什么想法吗?
    【解决方案2】:

    这样不行,

    基本上,您有另一个用于地址的数据库表,这意味着这些地址必须保存在数据库中,以便它们可以具有标识符和 user_id。

    我建议为地址创建另一个存储库。 每当您需要向用户添加地址时 做这样的事情:

    @PostMapping("/user/{id}/addAddress")
    public Address addAddressToUser(@RequestBody Address newAddress, @PathVariable(name="id") int userId)
    {
        User selectedUser = userRepo.findById(userId).orElseThrow( /* throw your exception */);
        newAddress.setUser( selectedUser );
    
        return addressRepo.save( newAddress )
    }
    

    基本上你必须像这样拨打电话:

    POST http://localhost:8080/user/1/addAddress
    

    在请求正文中有一个 Json :

    {
        "description" : "This is a new Address"
    }
    

    更新: 根据提问者的要求,这是一种在一次调用中执行此操作的方法,其中包含用户和地址。 代码未编译,但逻辑清晰。

    @PostMapping("/addUser)
    public User addUser(@RequestBody User newUser)
    {
        List<Address> addresses = newUser.getAddresses(); // We take all the addresses that are in the call
            
        newUser.setAddresses(new List<Address>()) // We empty the addresses in this User
            
        //Now for each address that was in the call, we save it the DB add it to user    
        addresses.forEach( address ->
        {
            address = addressRepo.save(address) // saves each address in the DB
            
            newUser.getAddresses().add(address); // add this Address to this user (SINCE NOW IT HAS AN ID IN THE DB)
        });
        
        //After everything is finished save this user to the Db with the Addresses and return it
        return userRepo.save(newUser);    
        
        
    }
    

    【讨论】:

    • 问题是我必须在同一个电话上做。是否可以先保存用户再保存地址?
    • 但是您还没有 User_id,您如何将这些地址与该特定用户联系起来?所以基本上把所有的地址都保存在另一个变量中。之后从用户中删除它们保存用户并将存储库返回的值放入变量中。并为每个你想保存的地址设置他们的用户这样 setUser(ThisNewUser) 然后保存每个地址。​​
    • 我对问题做了一个更新,我在User类中添加了这个addAddress,我是这么想的但不知道怎么调用它,你能检查一下吗?
    • 再次检查我的答案,您必须首先将地址保存在数据库中,以便休眠可以通过外键(FK)在用户和地址之间建立连接。所以你不仅要开始考虑面向对象,还要考虑数据库以及一切是如何连接的。
    • @Renis1235 cascade = CascadeType.ALL 表示您不必在用户面前保存地址。
    猜你喜欢
    • 2016-03-08
    • 2019-06-12
    • 2021-07-26
    • 2017-08-11
    • 2021-06-15
    • 1970-01-01
    • 2021-09-15
    • 2018-09-04
    • 1970-01-01
    相关资源
    最近更新 更多