maistack123
maistack123

Reputation: 145

Java - Spring Boot - Hibernate - JPA (Error with post @ManyToOne)

I have two models, one for the customer and one for the seller, in the customer table I need to have only one seller, already in the seller table, I can have several customers for a single seller.

But when I try to add a new customer, setting the salesperson's id, it just doesn't work.

Here is the code:


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

enter image description here

enter image description here

"entityName": "com.crud.spring.jpa.postgresql.model.Client", "propertyName": "seller", "message": "not-null property references a null or transient value : com.crud.spring.jpa.postgresql.model.Client.seller", "localizedMessage": "not-null property references a null or transient value : com.crud.spring.jpa.postgresql.model.Client.seller", "suppressed": [] "message": "not-null property references a null or transient value : com.crud.spring.jpa.postgresql.model.Client.seller; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : com.crud.spring.jpa.postgresql.model.Client.seller", enter code here"localizedMessage": "not-null property references a null or transient value : com.crud.spring.jpa.postgresql.model.Client.seller; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : com.crud.spring.jpa.postgresql.model.Client.seller",

Upvotes: 1

Views: 323

Answers (3)

Surjeet Singh Rathore
Surjeet Singh Rathore

Reputation: 71

So , there are few corrections : When your payload contains existing seller's id :

  1. Send existing seller id with payload
{
    "code" : 216,
    "name" : "addclientforseller5",
    "seller" :
        {
            "id" : 5
        }   
}

  1. Add this code in your service Implementation

    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
    }

When your payload contains Seller object to create new Seller do this :

  1. payload should look like this
{
    "code" : 112,
    "name" : "Pure",
    "seller" :{
        "code" : 1111,
        "name" : "Guava"
    }
}
  1. add this code in your service Implementation
    @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. remove @JsonIngnore from seller field in Client class.
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "seller_id", referencedColumnName = "id")
    @OnDelete(action = OnDeleteAction.CASCADE)
    //@JsonIgnore
    private Seller seller;

Upvotes: 1

Init_Rebel
Init_Rebel

Reputation: 68

I've simulated your code & have the below observations to make it work.

  • Remove @JsonIgnore Annotation from the Client Model
  • Jpa works based on the object references & not the values alone. So you might have to modify the Client service code.
 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);
        }

In the above code, we use the seller id from our request client model & get the seller object from db. Then we set the reference to the client model.

  • Pass the Json input for createClient as shown
{
    "id": 1,
    "code": 2,
    "name": "Client_1",
    "seller": {
        "id": 1
    }
}

Note: You'll have to create a valid seller first before creating the client by passing the seller id.

Upvotes: 1

Belaid BOUAOUALTEN
Belaid BOUAOUALTEN

Reputation: 391

try in json "seller":{"id":15} insted of "seller_id":15

Upvotes: 2

Related Questions