[SPRING] JSON 시리얼 라이저에서 지연로드 오류
SPRINGJSON 시리얼 라이저에서 지연로드 오류
나는 그런 종류의 @OneToOne Hibernate relationShip을 가지고있다.
public class Address implements Serializable {
private String id;
private String city;
private String country;
//setter getters ommitted
}
public class Student implements Serializable {
private String id;
private String firstName;
private String lastName;
private Address address;
}
주소 항목은 LAZY로 매핑됩니다.
이제 사용자를 불러오고 주소를 사용하고 싶습니다.
session.load(Student.class,id);
내 DAO 서비스.
그런 다음 스프링 MVC 컨트롤러에서 JSON으로 리턴한다.
@RequestMapping(value="/getStudent.do",method=RequestMethod.POST)
@ResponseBody
public Student getStudent(@RequestParam("studentId") String id){
Student student = daoService.getStudent(id);
return student;
}
불행히도 Lazy 클래스로 인해 작동하지 않습니다.
org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.vanilla.objects.Student_$$_javassist_1["address"]->com.vanilla.objects.Address_$$_javassist_0["handler"])
at org.codehaus.jackson.map.ser.StdSerializerProvider$1.serialize(StdSerializerProvider.java:62)
OpenSessionInViewInterceptor를 사용하고 잘 작동합니다. 나는 사용자가 HQL 질의에 참여하고 학생과 주소를 검색하여 문제를 해결할 수 있음을 이해한다. 또한 EAGER와의 관계를 바꾸면 해결 될 수 있음을 이해합니다.
하지만 표준 잭슨 메시지 변환기를 사용하여 JSON 지연 클래스에 직렬화 할 수 있습니다. 원인은 XML 파일에 추가 된 원인입니다.
해결법
-
==============================
1.가장 쉬운 솔루션 : 엔티티를 직렬화하지 않고 값 객체를 사용하십시오.
가장 쉬운 솔루션 : 엔티티를 직렬화하지 않고 값 객체를 사용하십시오.
이것이 옵션이 아니라면 엔티티 객체가 분리되었는지 확인하십시오.
JPA (2)를 사용하면 EntityManager.detach (entity)를 사용하고, 평이한 Hibernate는 Session.evict (entity)와 동등합니다.
-
==============================
2.일단 내가 이것을 처리하기위한 프로세서를 작성했지만 지금은 jackson hibernate 모듈을 사용하여 이것을 고칠 수있다.
일단 내가 이것을 처리하기위한 프로세서를 작성했지만 지금은 jackson hibernate 모듈을 사용하여 이것을 고칠 수있다.
-
==============================
3.DAO 메소드 내에서 Hibernate.initialize (
)를 추가하십시오. 이 문제를 해결하십시오. DAO 메소드 내에서 Hibernate.initialize (
)를 추가하십시오. 이 문제를 해결하십시오. Student student = findById(<yourId>); Hibernate.initialize(student.getAddress()); ... return student;
위와 같이 시도하십시오.
-
==============================
4.문제를 해결하는 또 다른 옵션이 있습니다. 이 필터는 web.xml에 추가 할 수 있습니다.
문제를 해결하는 또 다른 옵션이 있습니다. 이 필터는 web.xml에 추가 할 수 있습니다.
<filter> <filter-name>springOpenEntityManagerInViewFilter</filter-name> <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> <init-param> <param-name>entityManagerFactoryBeanName</param-name> <param-value>entityManagerFactory</param-value> </init-param> </filter> <filter-mapping> <filter-name>springOpenEntityManagerInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
문제는 엔터티가 느슨하게로드되고 직렬화가 완전히로드되기 전에 발생한다는 것입니다.
-
==============================
5.우선,이 문제를 해결하기 위해서만 DTO / Value Object를 사용할 것을 권장하지 않습니다. 처음에는 쉽게 찾을 수 있지만 새로 개발 / 변경 될 때마다 중복 코드 란 매번 두 번씩 수정하는 것을 의미합니다. 그렇지 않으면 버그가 발생합니다.
우선,이 문제를 해결하기 위해서만 DTO / Value Object를 사용할 것을 권장하지 않습니다. 처음에는 쉽게 찾을 수 있지만 새로 개발 / 변경 될 때마다 중복 코드 란 매번 두 번씩 수정하는 것을 의미합니다. 그렇지 않으면 버그가 발생합니다.
나는 VO 나 DTO가 나쁜 냄새가 나는 것은 아니지만 논리적 계층에 따라 다른 내용 / 구조를 제공하거나 해결할 수없는 직렬화 문제를 해결하는 것과 같이 설계된 이유로 사용해야 함을 의미합니다. VO / DTO없이 직렬화 문제를 해결할 수있는 깨끗하고 효율적인 방법이 있고 필요하지 않으면이를 사용하지 마십시오.
그리고 그것에 대해서, 당신이 Hibernate 엔티티와 함께 Jackson을 사용할 때 게으른 로딩 문제를 푸는 많은 방법이 있습니다.
실제로 가장 간단한 방법은 FasterXML / jackson-datatype-hibernate를 사용하는 것입니다.
그것은 Hibernate3Module / Hibernate4Module / Hibernate5Module을 제공한다.이 모듈은 Hibernate 특이성과 관련된 잘 정의 된 확장 집합을 제공하기 위해 ObjectMapper에 등록 할 수있는 확장 모듈이다.
이 작업을 수행하려면 필요한 종속성을 추가하고 Jackson Module은 필요한 곳에서 처리가 가능합니다.
최대 절전 모드 3을 사용하는 경우 :
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-hibernate3</artifactId> <version>${jackson.version.datatype}</version> </dependency>
최대 절전 모드 4를 사용하는 경우 :
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-hibernate4</artifactId> <version>${jackson.version.datatype}</version> </dependency>
그래서 ...
jackson.version.datatype은 사용 된 Jackson 버전과 ackson-datatype 확장자에 대해 동일해야합니다.
Spring Boot를 사용하거나 사용한다면, 특정 Configuration 클래스 나 SpringBootApplication 클래스에서 Bean으로 선언 할 필요가 있으며 생성 된 Jackson ObjectMapper에 대해 자동으로 등록됩니다.
74.3 Jackson ObjectMapper Spring Boot 사용자 정의 섹션에는 다음 내용이 나와 있습니다.
예 :
@Configuration public class MyJacksonConfig { @Bean public Module hibernate5Module() { return new Hibernate5Module(); } }
또는 :
@SpringBootApplication public class AppConfig { public static void main(String[] args) throws IOException { SpringApplication.run(AppConfig.class, args); } @Bean public Module hibernate5Module() { return new Hibernate5Module(); } }
from https://stackoverflow.com/questions/6277439/lazy-loadng-error-in-json-serializer by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] ajax spring mvc에서 ModelAndView 리턴하기 (0) | 2019.02.24 |
---|---|
[SPRING] hibernate-validator의 예외. 상자의 예외는 java.lang.NoClassDefFoundError입니다 : ConfigurationImpl (0) | 2019.02.24 |
[SPRING] Spring : 필터에서 컨트롤러로 객체를 전달하는 방법 (0) | 2019.02.24 |
[SPRING] Spring-Boot, 스프링 데이터 JPA를 사용하여 MySql의 유니 코드 문자열을 저장할 수 없음 (0) | 2019.02.24 |
[SPRING] 스프링 컨트롤러에서 angularjs의 모델 속성 값을 얻는 방법 (0) | 2019.02.24 |