Spring boot @ResponseBody не сериализует идентификатор объекта

Имейте странную проблему и не можете понять, как с этим бороться. Простые POJO:

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

и конечная точка restа:

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

В json-ответе есть все поля, кроме Id, которые мне нужны на лицевой стороне для редактирования / удаления человека. Как настроить весеннюю загрузку для сериализации идентификатора?

Вот как выглядит ответ:

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

UPD Имеет двунаправленное отображение гибернации, возможно, это как-то связано с проблемой.

У меня недавно была такая же проблема, и это потому, что по умолчанию работает spring-boot-starter-data-rest . См. Мой вопрос SO -> При использовании Spring Data Rest после переноса приложения в Spring Boot я заметил, что свойства объекта с @Id больше не сортируются в JSON

Чтобы настроить способ его поведения, вы можете расширить RepositoryRestConfigurerAdapter чтобы выставлять идентификаторы для определенных classов.

 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 protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.exposeIdsFor(Person.class); } } 

Ответ от @ eric-peladan не сработал из коробки, но был довольно близок, возможно, это работало на предыдущие версии Spring Boot. Теперь вот как это должно быть настроено вместо этого, исправьте меня, если я ошибаюсь:

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

Если вам нужно выставить идентификаторы для всех объектов :

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

Если вы хотите показывать только идентификаторы объектов, которые расширяют или реализуют определенный суперclass или интерфейс :

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

Если вы хотите показывать идентификаторы объектов с определенной аннотацией :

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

Пример annotations:

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

С Spring Boot вы должны расширить SpringBootRepositoryRestMvcConfiguration
если вы используете RepositoryRestMvcConfiguration, определение конфигурации в application.properties может не работать

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

Но для временной необходимости Вы можете использовать проекцию для включения id в сериализацию, например:

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

}

Хм, ок, похоже, я нашел решение. Удаление исходных данных из файла pom и добавление @JsonManagedReference к phoneNumbers и @JsonBackReference для человека дает желаемый результат. Json в ответе уже не печатается, но теперь у него есть Id. Не знаю, что волшебная весенняя ботинок работает под капотом с этой зависимостью, но мне это не нравится 🙂

Простой способ: переименовать переменную private Long id; private Long Id;

Работает на меня. Вы можете узнать больше об этом здесь

Давайте будем гением компьютера.