【问题标题】:Java - Spring Boot - Hibernate - JPA (Error with post @ManyToOne)Java - Spring Boot - Hibernate - JPA(@ManyToOne 发布错误)
【发布时间】:2021-07-26 22:36:30
【问题描述】:

我有两个模型,一个给客户,一个给卖家,在客户表中我只需要一个卖家,已经在卖家表中,我可以为一个卖家有多个客户。

但是当我尝试添加新客户并设置销售人员的 ID 时,它就不起作用了。

代码如下:

  • 卖家型号:

    package com.crud.spring.jpa.postgresql.model;
    
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.Setter;
    
    import javax.persistence.*;
    
    @Entity
    @AllArgsConstructor
    @Getter
    @Setter
    @Table(name = "sellers", uniqueConstraints = @UniqueConstraint(columnNames = "code"))
    public class Seller {
    
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;
    
      @Column(name = "code")
      private long code;
    
      @Column(name = "name")
      private String name;
    
      public Seller(){
      }
    }

  • 客户端模型:

    package com.crud.spring.jpa.postgresql.model;
    
    import com.fasterxml.jackson.annotation.JsonIgnore;
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.Setter;
    import org.hibernate.annotations.OnDelete;
    import org.hibernate.annotations.OnDeleteAction;
    
    import javax.persistence.*;
    
    @Entity
    @AllArgsConstructor
    @Getter
    @Setter
    @Table(name = "clients", uniqueConstraints = @UniqueConstraint(columnNames = "code"))
    public class Client {
    
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;
    
      @Column(name = "code")
      private long code;
    
      @Column(name = "name")
      private String name;
    
      @ManyToOne(fetch = FetchType.LAZY, optional = false)
      @JoinColumn(name = "seller_id", referencedColumnName = "id", nullable = false)
      @OnDelete(action = OnDeleteAction.CASCADE)
      @JsonIgnore
      private Seller seller;
    
      public Client(){
      }
    }

  • 客户端控制器:

    @PostMapping("/clients")
    public ResponseEntity createClients(@RequestBody Client client) {
      return this.service.createClients(client);
    }

  • 客户服务:

    public ResponseEntity createClients(Client client) {
      try {
        client = this.repository.save(client);
    
        return new ResponseEntity(client, HttpStatus.OK);
      } catch (Exception e){
        return new ResponseEntity(e, HttpStatus.INTERNAL_SERVER_ERROR);
      }
    }

  • 后卖家:

  • 发布客户:

  • 错误是:

"entityName": "com.crud.spring.jpa.postgresql.model.Client", "propertyName": "seller", "message": "not-null property references a 空值或瞬态值: com.crud.spring.jpa.postgresql.model.Client.seller", "localizedMessage": "非空属性引用空或瞬态 值:com.crud.spring.jpa.postgresql.model.Client.seller", "suppressed": [] "message": "not-null 属性引用了一个 null 或 瞬态值:com.crud.spring.jpa.postgresql.model.Client.seller; 嵌套异常是 org.hibernate.PropertyValueException: not-null 属性引用空值或瞬态值: com.crud.spring.jpa.postgresql.model.Client.seller", enter code here"localizedMessage": "not-null 属性引用了 null 或 瞬态值:com.crud.spring.jpa.postgresql.model.Client.seller; 嵌套异常是 org.hibernate.PropertyValueException: not-null 属性引用空值或瞬态值: com.crud.spring.jpa.postgresql.model.Client.seller",

【问题讨论】:

    标签: java spring spring-boot hibernate jpa


    【解决方案1】:

    尝试使用 json "seller":{"id":15} insted of "seller_id":15

    【讨论】:

    • 不要这样做。我如何这样工作:{ "code": 1, "name": "Eduardo", "seller_id": 15 }
    • { "code": 1, "name": "Eduardo","seller":{"id":15}} 你应该这样尝试,因为当你引用卖家时,你引用了一个你会通过它的 id 找到的类
    • 我设法改善了帖子中代码的可视化,您可以再检查一下吗?
    【解决方案2】:

    所以,有一些更正: 当您的有效载荷包含现有卖家的 id 时:

    1. 使用有效负载发送现有卖家 ID
    {
        "code" : 216,
        "name" : "addclientforseller5",
        "seller" :
            {
                "id" : 5
            }   
    }
    
    
    1. 在您的服务实现中添加此代码
    
        public Client createClients(Client client) {
            Long sellerId = client.getSeller().getId();
            Optional<Seller> existingSeller = sellerRepository.findById(sellerId);
            if (existingSeller.isPresent()) {
                Seller savedSellerObject = existingSeller.get();
                client.setSeller(savedSellerObject);
            } else {
                // throw exception
            }
    
            return clientSellerRepository.save(client); // you can return ResponseEntity also
        }
    

    当您的有效负载包含卖家对象以创建新卖家时,请执行以下操作:

    1. 有效负载应如下所示
    {
        "code" : 112,
        "name" : "Pure",
        "seller" :{
            "code" : 1111,
            "name" : "Guava"
        }
    }
    
    1. 将此代码添加到您的服务实现中
        @Autowired
        ClientRepository clientRepository;
    
        @Autowired
        SellerRepository sellerRepository;
    
    public Client createClients(Client client) {
            Seller seller = new Seller();
            seller.setCode(client.getSeller().getCode());
            seller.setName(client.getSeller().getName());
            Seller savedSeller = sellerRepository.save(seller);
            client.setSeller(savedSeller);
            return clientRepository.save(client);
        }
    
    1. 从客户端类的卖方字段中删除 @JsonIngnore。
        @ManyToOne(fetch = FetchType.LAZY, optional = false)
        @JoinColumn(name = "seller_id", referencedColumnName = "id")
        @OnDelete(action = OnDeleteAction.CASCADE)
        //@JsonIgnore
        private Seller seller;
    

    【讨论】:

    • 不要这样做。我该如何工作:``` { "code": 1, "name": "Eduardo", "seller_id": 15 } ``
    • 无法在有效负载中按照您的意愿发送请求。
    • 我设法改进了帖子中代码的可视化,您可以再检查一下吗?
    • 好的。如果我的回答解决了您的问题。请投票。
    • 我不能只引用 ID 而不是客户端中的整个卖家对象吗?
    【解决方案3】:

    我已经模拟了您的代码并有以下观察结果以使其正常工作。

    • 从客户端模型中移除 @JsonIgnore 注解
    • Jpa 基于对象引用而不是单独的值工作。因此,您可能需要修改客户端服务代码。
     try {
               Optional<Seller> seller = sellerRepository.findById(client.getSeller().getId());
               if(seller.isPresent()){
                   client.setSeller(seller.get());
                   client = this.repository.save(client);
               }
                return new ResponseEntity(client, HttpStatus.OK);
            } catch (Exception e) {
                return new ResponseEntity(e, HttpStatus.INTERNAL_SERVER_ERROR);
            }
    

    在上面的代码中,我们使用请求客户端模型中的卖家 ID 并从 db 中获取卖家对象。然后我们设置对客户端模型的引用。

    • 为 createClient 传递 Json 输入,如图所示
    {
        "id": 1,
        "code": 2,
        "name": "Client_1",
        "seller": {
            "id": 1
        }
    }
    

    注意:您必须先创建一个有效的卖家,然后才能通过传递卖家 ID 创建客户端。

    【讨论】:

      猜你喜欢
      • 2016-03-08
      • 2021-06-15
      • 1970-01-01
      • 2021-12-13
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 2016-09-17
      • 2020-02-04
      相关资源
      最近更新 更多