Amorçage du spring @ResponseBody ne sérialise pas l’identifiant de l’entité

Avoir un problème étrange et ne pas comprendre comment y faire face. Avoir simple POJO:

@Entity @Table(name = "persons") public class Person { @Id @GeneratedValue private Long id; @Column(name = "first_name") private Ssortingng firstName; @Column(name = "middle_name") private Ssortingng middleName; @Column(name = "last_name") private Ssortingng lastName; @Column(name = "comment") private Ssortingng comment; @Column(name = "created") private Date created; @Column(name = "updated") private Date updated; @PrePersist protected void onCreate() { created = new Date(); } @PreUpdate protected void onUpdate() { updated = new Date(); } @Valid @OrderBy("id") @OneToMany(mappedBy = "person", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) private List phoneNumbers = new ArrayList(); public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getMiddleName() { return middleName; } public void setMiddleName(String middleName) { this.middleName = middleName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getComment() { return comment; } public void setComment(String comment) { this.comment = comment; } public Date getCreated() { return created; } public Date getUpdated() { return updated; } public List getPhoneNumbers() { return phoneNumbers; } public void addPhoneNumber(PhoneNumber number) { number.setPerson(this); phoneNumbers.add(number); } @Override public Ssortingng toSsortingng() { return ToSsortingngBuilder.reflectionToSsortingng(this, ToSsortingngStyle.SHORT_PREFIX_STYLE); } } @Entity @Table(name = "phone_numbers") public class PhoneNumber { public PhoneNumber() {} public PhoneNumber(Ssortingng phoneNumber) { this.phoneNumber = phoneNumber; } @Id @GeneratedValue private Long id; @Column(name = "phone_number") private Ssortingng phoneNumber; @ManyToOne @JoinColumn(name = "person_id") private Person person; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Ssortingng getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(Ssortingng phoneNumber) { this.phoneNumber = phoneNumber; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } @Override public Ssortingng toSsortingng() { return ToSsortingngBuilder.reflectionToSsortingng(this, ToSsortingngStyle.SHORT_PREFIX_STYLE); } } 

et point final de repos:

 @ResponseBody @RequestMapping(method = RequestMethod.GET) public List listPersons() { return personService.findAll(); } 

Dans la réponse json, il y a tous les champs sauf Id, dont j’ai besoin sur le côté frontal pour modifier / supprimer une personne. Comment puis-je configurer le démarrage à ressort pour sérialiser également l’ID?

Voilà comment la réponse ressemble maintenant:

 [{ "firstName": "Just", "middleName": "Test", "lastName": "Name", "comment": "Just a comment", "created": 1405774380410, "updated": null, "phoneNumbers": [{ "phoneNumber": "74575754757" }, { "phoneNumber": "575757547" }, { "phoneNumber": "57547547547" }] }] 

UPD Avoir un mappage d’hibernation bidirectionnel, peut-être lié à un problème.

J’ai récemment eu le même problème et c’est parce que c’est comme ça que spring-boot-starter-data-rest fonctionne par défaut. Voir ma question SO -> Lors de l’utilisation de Spring Data Rest après la migration d’une application vers Spring Boot, j’ai observé que les propriétés d’entité avec @Id ne sont plus classées en JSON

Pour personnaliser son comportement, vous pouvez étendre RepositoryRestConfigurerAdapter pour exposer les ID de classes spécifiques.

 import org.springframework.context.annotation.Configuration; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter; @Configuration public class RepositoryConfig extends RepositoryRestConfigurerAdapter { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.exposeIdsFor(Person.class); } } 

La réponse de @ eric-peladan n’a pas fonctionné, mais était assez proche, peut-être que cela fonctionnait pour les versions précédentes de Spring Boot. Maintenant, voici comment il est censé être configuré à la place, corrigez-moi si je me trompe:

 import org.springframework.context.annotation.Configuration; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter; @Configuration public class RepositoryConfiguration extends RepositoryRestConfigurerAdapter { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.exposeIdsFor(User.class); config.exposeIdsFor(Comment.class); } } 

Si vous devez exposer les identificateurs de toutes les entités :

 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter; import javax.persistence.EntityManager; import javax.persistence.metamodel.Type; @Configuration public class RestConfiguration extends RepositoryRestConfigurerAdapter { @Autowired private EntityManager entityManager; @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.exposeIdsFor( entityManager.getMetamodel().getEntities().stream() .map(Type::getJavaType) .toArray(Class[]::new)); } } 

Si vous souhaitez uniquement exposer les identificateurs d’entités qui étendent ou implémentent une super-classe ou une interface spécifique :

  ... @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.exposeIdsFor( entityManager.getMetamodel().getEntities().stream() .map(Type::getJavaType) .filter(Identifiable.class::isAssignableFrom) .toArray(Class[]::new)); } 

Si vous souhaitez uniquement exposer les identificateurs d’entités avec une annotation spécifique :

  ... @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.exposeIdsFor( entityManager.getMetamodel().getEntities().stream() .map(Type::getJavaType) .filter(c -> c.isAnnotationPresent(ExposeId.class)) .toArray(Class[]::new)); } 

Exemple d’annotation:

 import java.lang.annotation.*; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ExposeId {} 

Avec Spring Boot, vous devez étendre SpringBootRepositoryRestMvcConfiguration
si vous utilisez RepositoryRestMvcConfiguration, la configuration définie dans application.properties peut ne pas fonctionner

 @Configuration public class MyConfiguration extends SpringBootRepositoryRestMvcConfiguration { @Override protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.exposeIdsFor(Project.class); } } 

Mais pour un besoin temporaire Vous pouvez utiliser la projection pour inclure id dans la sérialisation comme:

 @Projection(name = "allparam", types = { Person.class }) public interface ProjectionPerson { Integer getIdPerson(); Ssortingng getFirstName(); Ssortingng getLastName(); 

}

Hm, ok semble avoir trouvé la solution. Suppression de spring-boot-starter-data-rest du fichier pom et ajout de @JsonManagedReference à phoneNumbers et @JsonBackReference à person donne la sortie souhaitée. Json, en réponse, n’est plus assez imprimé, mais il a maintenant un identifiant. Je ne sais pas quelle botte de spring magique fonctionne sous le capot avec cette dépendance mais je ne l’aime pas 🙂

Moyen facile: renommez votre variable private Long id; à private Long Id;

Travaille pour moi. Vous pouvez en lire plus à ce sujet ici