스프링 부트 @ResponseBody가 엔티티 ID를 직렬화하지 않음
이상한 문제가 생겨서 어떻게 대처해야 할지 모르겠어요.간단한 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<PhoneNumber> 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<PhoneNumber> 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 endpoint:
@ResponseBody
@RequestMapping(method = RequestMethod.GET)
public List<Person> listPersons() {
return personService.findAll();
}
json response에는 Id를 제외한 모든 필드가 있으며, 이 필드는 사용자를 편집/삭제하기 위해 프런트 엔드에 필요합니다.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 Boot으로 앱을 이행한 후 Spring Data Rest를 사용하는 동안 @Id의 엔티티 속성이 JSON에 마샬링되지 않게 되었습니다.
을 커스터마이즈 , 「」를 합니다.RepositoryRestConfigurerAdapter
아이디
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);
}
}
모든 엔티티에 대한 식별자를 노출해야 하는 경우:
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.RepositoryRestConfigurer;
import javax.persistence.EntityManager;
import javax.persistence.metamodel.Type;
@Configuration
public class RestConfiguration implements RepositoryRestConfigurer {
@Autowired
private EntityManager entityManager;
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(
entityManager.getMetamodel().getEntities().stream()
.map(Type::getJavaType)
.toArray(Class[]::new));
}
}
Spring Boot보다 에서는 " " 입니다.2.1.0.RELEASE
(지금은 사용되지 않음)를 확장해야 합니다. org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter
RepositoryRestConfigurer
직접적으로.
특정 슈퍼 클래스 또는 인터페이스를 확장 또는 구현하는 엔티티 식별자만 공개하는 경우:
...
@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));
}
주석 예:
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExposeId {}
@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);
}
}
★★★★RepositoryRestConfigurerAdapter
되어 3.을 구현합니다.RepositoryRestConfigurer
직접적으로.
@Configuration
public class RepositoryConfiguration implements RepositoryRestConfigurer {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(YouClass.class);
RepositoryRestConfigurer.super.configureRepositoryRestConfiguration(config);
}
}
폰트: https://docs.spring.io/spring-data/rest/docs/current-SNAPSHOT/api/org/springframework/data/rest/webmvc/config/RepositoryRestConfigurer.html
Spring Boot에서는 Spring Boot Repository RestMvc Configuration을 확장해야 합니다.
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();
}
ID에 @JsonProperty 주석을 추가하면 작동합니다.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonProperty
private long id;
은 '실행하다' 입니다.RepositoryRestConfigurerAdapter
이은 할 때 하게 쓰일 것입니다.
@Component
public class EntityExposingIdConfiguration extends RepositoryRestConfigurerAdapter {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
try {
Field exposeIdsFor = RepositoryRestConfiguration.class.getDeclaredField("exposeIdsFor");
exposeIdsFor.setAccessible(true);
ReflectionUtils.setField(exposeIdsFor, config, new ListAlwaysContains());
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
class ListAlwaysContains extends ArrayList {
@Override
public boolean contains(Object o) {
return true;
}
}
}
음, 좋아, 내가 해결책을 찾은 것 같아.pom 파일에서 spring-boot-starter-data-rest를 삭제하고 phoneNumbers에 @JsonManagedReference를 추가하고 phoneNumbers에 @JsonBackReference를 추가하면 원하는 출력을 얻을 수 있습니다.Json은 더 이상 인쇄가 잘 되지 않지만 ID를 가지고 있습니다.이 의존관계에 있는 후드 아래에서 매직 스프링 부츠가 어떤 역할을 하는지 모르겠지만, 저는 그것이 마음에 들지 않습니다:)
간단한 방법: 변수 이름 바꾸기private Long id;
로.private Long Id;
저는 좋아요.자세한 내용은 이쪽에서 확인하실 수 있습니다.
의 실장RepositoryRestConfigurer
및 사용@Configuration
코멘트를 표시합니다.
여기 토막이 있습니다.
@Configuration
public class BasicConfig implements RepositoryRestConfigurer{
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
// TODO Auto-generated method stub
config.exposeIdsFor(Person.class);
}
}
언급URL : https://stackoverflow.com/questions/24839760/spring-boot-responsebody-doesnt-serialize-entity-id
'programing' 카테고리의 다른 글
PHP에서 문자열을 올바르게 인코딩하려면 어떻게 해야 합니까? (0) | 2022.11.01 |
---|---|
LIKE 문을 사용하여 PDO 파라미터화된 쿼리를 작성하려면 어떻게 해야 합니까? (0) | 2022.11.01 |
MySQL의 DESCRIPT [표]와 동등한 SQLite가 있습니까? (0) | 2022.11.01 |
phpMyAdmin 행을 편집 또는 삭제하려고 하면 오류 #1064가 나타납니다. (0) | 2022.11.01 |
Lombok이 추가했지만 Intellij IDEA에서 getters와 setters가 인식되지 않음 (0) | 2022.11.01 |