“ManyToOne在Spring Boot Hibernate JPA中创建两个表时返回null”

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

ManyToOne gives null on two tables on create spring boot hiernate jpa

问题

例如,如果有表格"用户"和"地址",并且一个用户可以有一个到多个地址,所以关系是一对多。当我插入数据时,我会在同一个 JSON 中插入用户和地址列表。

问题是,在创建时,连接这两者的字段为空。我找不到正确的方法来插入数据,使其创建所有这些数据,然后也填充一对多关系所在的字段。

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

在一个表中:

@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;
}

我发送了一个创建新用户并附带一些地址的 POST 请求:

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

在 POST 请求中,我发送了这个 JSON:

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

当我插入数据时,在"地址"表中,"user_id" 为空,数据被插入,但关系不在那里?
我在这里做错了什么? 请帮忙!

更新:
我考虑了像这样的做法,但不知道该如何调用它:

public class User {

    ....

    public void addAddress(Address address) {
        address.setUser(this);
        addresses.add(address);
    }
}
英文:

For example if have table "user" and "address" and a user can have 1 to more addresses, so the relation is one to many. When I insert data I will insert inside the same json the user and the address list.

The problem is that on create the field that related these two is null. I can't find the right way how to insert data so it will create all of these and then populate also the field where onetomany relation is done.

I have two tables which are related to each other, table "user" and "address":

@Entity
@Table(name = &quot;user&quot;)
@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 = &quot;user&quot;, cascade = CascadeType.ALL, orphanRemoval = true)
    protected Set&lt;Address&gt; addresses= new HashSet&lt;&gt;();
}

While in the other table:

@Entity
@Table(name = &quot;address&quot;)
@Data
public class Address{

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

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

    private String description;
}

I did a post request to create new user with some addresses:

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

In a post request I sent this json:

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

When I insert data I get the "address" table the "user_id" is null, the data are inserted but the relations are not there?
What I'm doing wrong here? Please help!

Update:
I thought on doing something like this but don't know how to call it:

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

}

答案1

得分: 1

不是这样工作的,

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

我建议为地址创建另一个存储库。
每当您需要为用户添加地址时,请按以下方式操作:

@PostMapping("/user/{id}/addAddress")
public Address addAddressToUser(@RequestBody Address newAddress, @PathVariable(name="id") int userId)
{
    User selectedUser = userRepo.findById(userId).orElseThrow( /* 抛出您的异常 */);
    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(); // 我们获取调用中的所有地址
    
    newUser.setAddresses(new ArrayList<>()); // 我们清空此用户中的地址
    
    // 现在对于调用中的每个地址,我们将其保存到DB并将其添加到用户中
    addresses.forEach(address ->
    {
        address = addressRepo.save(address); // 在DB中保存每个地址
        
        newUser.getAddresses().add(address); // 将此地址添加到此用户中(因为它现在在DB中有一个ID)
    });
    
    // 在所有事情都完成后,将此用户保存到数据库中并返回它
    return userRepo.save(newUser);    
}
英文:

It doesn't work like that,

Basically you have another DB table for adresses and that means that these addresses have to be saved in the Database, so that they can have an identifier and user_id.

I would recommend creating another Repository for addresses.
And whenever you need to add an Address to a User
Do something like this:

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

    return addressRepo.save( newAddress )
}

And basically you have to make a call like this:

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

And in the Request body a Json :

{
    &quot;description&quot; : &quot;This is a new Address&quot;
}

UPDATE:
As requested by the asker, this is a way to perform this in one call with User and Addresses inside.
Code was not compiled, but logic is clear.

@PostMapping(&quot;/addUser)
public User addUser(@RequestBody User newUser)
{
    List&lt;Address&gt; addresses = newUser.getAddresses(); // We take all the addresses that are in the call
        
    newUser.setAddresses(new List&lt;Address&gt;()) // 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 -&gt;
    {
        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);    
    
    
}

答案2

得分: 0

你需要将其用于连接列(用户)=> @JoinColumn(name = "users_id",nullable = false)

英文:

You need to use it for join column(user) => @JoinColumn(name = "users_id",nullable = false)

huangapple
  • 本文由 发表于 2020年10月27日 17:45:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/64551770.html
匿名

发表评论

匿名网友

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

确定