2 votes

Problème de désérialisation de Spring boot JPA lors de la récupération de l'ID d'une autre entité

Je suis en train de créer un programme web pour cartographier les niveaux d'occupation des magasins avec spring boot, tomcat et JPA. J'ai déjà créé le modèle/service/contrôleur membre et il fonctionne correctement lorsque j'essaie de le mettre à jour, de le créer, de le supprimer ou d'obtenir des informations à partir de celui-ci.

Cependant, les magasins ne sont pas créés non plus. Lorsque je crée un magasin avec l'identifiant du propriétaire, j'obtiens un message d'erreur disant :

Message d'erreur

[org.springframework.http.converter.HttpMessageNotReadableException : Erreur d'analyse JSON : Impossible de construire une instance de com.project.so2.models.Member (bien qu'il existe au moins un Creator) : pas de méthode de construction/fabrication d'argument String pour désérialiser la valeur String ('1') ; l'exception imbriquée est com.fasterxml.jackson.databind.exc.MismatchedInputException : Impossible de construire une instance de com.project.so2.models.Member (bien qu'il existe au moins un Créateur) : pas de méthode de construction/fabrication d'argument String pour désérialiser la valeur String ('1') at [Source : (PushbackInputStream) ; line : 4, column : 18] (à travers la chaîne de référence : com.project.so2.models.Store["owner_id"])]

J'ai essayé de rechercher des problèmes similaires mais je n'ai pas vu de solution applicable.

Modèles

Magasins

@Entity(name = "Store")
@Table(name = "store")
@SequenceGenerator(name = "store_id")
public class Store {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "store_id")
    @Column(name = "id")
    private long id;

    //many stores to one owner
    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @JoinColumn(name = "owner_id", referencedColumnName = "id")
    private Member owner_id;

    //one store to many occupation level
    @OneToMany(mappedBy = "store")
    private List<Occupation> store_occupation;

    @OneToOne(mappedBy = "store")
    private Location location;

    @Column(name = "name")
    private String name;

    @Column(name = "square_footage")
    private String square_footage;

    public Store() {
    }

Membres

@Entity(name = "Member")
@Table(name = "member")
@SequenceGenerator(name = "member_id")
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_id")
    @Column(name = "id")
    private long id;

    @Enumerated(EnumType.STRING)
    @Column(name = "role")    
    private Role role;//customer|admin|store_owner

    @Column(name = "mail", unique = true)
    private String mail;

    @Column(name = "name")
    private String name;

    @OneToMany(mappedBy = "owner_id")
    private List<Store> stores;

    /**
     * REALM to store passwords
     */

    @CreationTimestamp
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date createdAt;

    @UpdateTimestamp
    private Date updateAt;

Contrôleur de magasin

@RestController
@RequestMapping("/store")
@ControllerAdvice()
@CrossOrigin
public class StoreController {
    @Autowired
    private StoreService storeservice;

    @PostMapping("/create")
    public ResponseEntity<HttpStatus> createStore(@RequestBody Store store) {
        try {
            this.storeservice.saveStore(store);
            return new ResponseEntity<>(HttpStatus.CREATED);
        } catch (Exception e) {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

Service des magasins

@Service
public class StoreService {

    @Autowired
    private StoreRepository storeRepository;//

    public void saveStore(Store store) {
        this.storeRepository.save(store); 
    }

Charge utile de la demande :

{
    "name": "Pingo Azedo",
    "square_footage": "25m^2",
    "owner_id":{
        "member_id": "1"
    }
}

Honnêtement, je ne comprends pas le problème et je ne sais pas comment le résoudre. Si quelqu'un peut m'aider, ce serait très apprécié !

1voto

Hưng Chu Points 733

Vous essayez de désérialiser le membre à partir de json, mais jackson ne sait pas comment remplir ce membre avec juste "member_id", et l'erreur est clairement dit ainsi "no constructer with String is found". Donc, afin d'obtenir l'id du membre, vous devez ajouter une nouvelle classe de demande dto, quelque chose comme :

String name;
String footage;
Long owner_id;

Utilisez votre nouvelle classe dans votre contrôleur, maintenant avec owner_id, utilisez repository pour le trouver dans votre db, puis définissez-le à votre magasin.

0voto

Yohan Aloka Points 71

Vous devez utiliser les noms de propriétés dans le payload, pas les noms de colonnes. Modifiez le payload de votre requête comme ci-dessous,

{
  "name": "Pingo Azedo",
  "square_footage": "25m^2",
  "owner_id":{
       "id" : 1
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X