Spring boot @ResponseBody no serializa la identidad de la entidad

Tiene un problema extraño y no puede entender cómo lidiar con él. Tener POJO simple:

@Entity @Table(name = "persons") public class Person { @Id @GeneratedValue private Long id; @Column(name = "first_name") private String firstName; @Column(name = "middle_name") private String middleName; @Column(name = "last_name") private String lastName; @Column(name = "comment") private String 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 String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } } @Entity @Table(name = "phone_numbers") public class PhoneNumber { public PhoneNumber() {} public PhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } @Id @GeneratedValue private Long id; @Column(name = "phone_number") private String phoneNumber; @ManyToOne @JoinColumn(name = "person_id") private Person person; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } } 

y punto final de descanso:

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

En la respuesta json hay todos los campos, excepto Id, que necesito en el anverso para editar / eliminar persona. ¿Cómo puedo configurar el arranque de resorte para serializar Id también?

Así es como se ve la respuesta ahora:

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

UPD Tiene un mapa de hibernación bidireccional, tal vez esté relacionado de alguna manera con el problema.

Hace poco tuve el mismo problema y es porque así es como funciona spring-boot-starter-data-rest de manera predeterminada. Vea mi pregunta sobre SO -> Mientras uso Spring Data Rest después de migrar una aplicación a Spring Boot, he observado que las propiedades de la entidad con @Id ya no están organizadas para JSON

Para personalizar cómo se comporta, puede extender RepositoryRestConfigurerAdapter para exponer ID para clases específicas.

 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 respuesta de @ eric-peladan no funcionó de la caja, pero estuvo bastante cerca, tal vez eso funcionó para versiones anteriores de Spring Boot. Ahora así es como se supone que debe configurarse, corrígeme si me equivoco:

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

En caso de que necesite exponer los identificadores para todas las entidades :

 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 solo desea exponer los identificadores de las entidades que amplían o implementan una súper clase o interfaz específica :

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

Si solo desea exponer los identificadores de las entidades con una anotación específica :

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

Anotación de muestra:

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

Con Spring Boot tienes que extender SpringBootRepositoryRestMvcConfiguration
si usa RepositoryRestMvcConfiguration, la configuración definida en application.properties puede no funcionar

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

Pero para una necesidad temporal, puede usar la proyección para incluir el ID en la serialización como:

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

}

Hm, parece que encontré la solución. Eliminando spring-boot-starter-data-rest del archivo pom y agregando @JsonManagedReference a phoneNumbers y @JsonBackReference a person, da el resultado deseado. Json en respuesta ya no está muy bien impreso, pero ahora tiene Id. No sé lo que la bota de muelles mágica realiza debajo de la capucha con esta dependencia, pero no me gusta 🙂

Manera fácil: cambie el nombre de su private Long id; variable private Long id; a private Long Id;

Funciona para mi. Puedes leer más sobre esto aquí