angularspring-bootrestangular-httpclient

One-to-one relationship in Spring Boot: Attribute is not saved from Angular frontend, but works in Postman


Why is the race object not being saved in the database when using my Angular app, but it works correctly via Postman?

´Hallo, I'm developing an application with Spring Boot and Angular. I have a Puppy entity with a delegated race object (represented by another entity class, Bread). These two entities have a One-to-One relationship. When saving data, the race attribute doesn't persist in the database when sent from my Angular app, but it works as expected when using the JSON body in Postman (Content-Type:application/json):

    {
    "id": null,
    "puppyId": 27,
    "name": "Welpe Max",
    "color": "Braun",
    "weight": 5.5,
    "height": 30.0,
    "image": "/assets/images/welps/maxxx.jpg",
    "characteristic": ["Friendly", "Curious"],
    "race": {
        "id": null,
        "race": "Haski"
    },
    "price": 450.99
}

and this is my Json Object in Angular:

const puppyJson = JSON.stringify({
    id: null,
    puppyId: this.puppy.puppyId,
    name: this.puppy.name,
    color: this.puppy.color,
    weight: this.puppy.weight,
    height: this.puppy.height,
    image: this.puppy.image,
    characteristic: this.puppy.characteristic,
    race: { id: null, race: this.puppy.race?.race }, 
    price: this.puppy.price
  });

In Angular I'm using HttpClient.post() with Content-Type: application/json to send the Puppy object as JSON.

In the backend I have SpringBoot. The Puppy class has a OneToOne relationship with race (in the Bread class). Both entities are annotated accordingly, and the race attribute is set in Puppy:


@Entity
@Data public class Puppy{
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long puppyId;
   private String name;
   private String color;
   private BigDecimal weight;
   private BigDecimal height;
   private String image;
   private BigDecimal price;

   @OneToOne(mappedBy="productObject", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
   private Bread race;

   // Getters and setters  
}

@Entity
public class Bread {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "race")
    private String race;
    
    @OneToOne
    @JoinColumn(name = "product_object_fk")
    private Puppy productObject;
    
    // Getters and setters
}

And at least my Restcontroller class:

    @CrossOrigin(origins = "http://localhost:4200")
    @RestController
    @RequestMapping("/upload")
    public class ResponseController {
    
         @Autowired 
         private PuppyService puppyService;
    
         @PostMapping(value="/addPuppy")
         public ResponseEntity<String> addPuppy(@RequestBody Puppy puppy) {
            
            puppyService.save(puppy);
            System.out.println(puppy.getImage());
        
            
            return ResponseEntity.ok("succed");
                
         }
    }
    



Solution

  • dude! In Postman, your JSON looks correct, but are you sure that this.puppy.race is really not undefined? You don't need to convert your object, because the Angular HTTP Client will handle that for you. Let Angular handle it.

     const puppyJson = {
      id: null,
      puppyId: this.puppy.puppyId,
      name: this.puppy.name,
      color: this.puppy.color,
      weight: this.puppy.weight,
      height: this.puppy.height,
      image: this.puppy.image,
      characteristic: this.puppy.characteristic,
      race: { id: null, race: this.puppy.race?.race }, 
      price: this.puppy.price
     };
    

    You can also debug your object to make sure everything looks correct before sending it.

    console.log(puppyJson)