Hibernate 객체를 직렬화 할 때 발생하는 이상한 Jackson 예외
Jackson은 내가 고치는 방법을 모르는 이상한 예외를 던지고 있습니다. 저는 Spring, Hibernate 및 Jackson을 사용하고 있습니다.
지연 로딩이 문제의 원인이라고 이미 고려했지만 Jackson에게 다음과 같이 다양한 속성을 처리하지 않도록 지시하는 조치를 취했습니다.
@JsonIgnoreProperties({ "sentMessages", "receivedMessages", "educationFacility" })
public class Director extends UserAccount implements EducationFacilityUser {
....
}
다른 모든 UserAccount 하위 클래스에 대해서도 동일한 작업을 수행했습니다.
throw되는 예외는 다음과 같습니다.
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: java.util.ArrayList[46]->jobprep.domain.educationfacility.Director_$$_javassist_2["handler"])
at org.codehaus.jackson.map.ser.StdSerializerProvider$1.serialize(StdSerializerProvider.java:62)
at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:268)
at org.codehaus.jackson.map.ser.BeanSerializer.serializeFields(BeanSerializer.java:146)
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:118)
at org.codehaus.jackson.map.ser.ContainerSerializers$IndexedListSerializer.serializeContents(ContainerSerializers.java:236)
at org.codehaus.jackson.map.ser.ContainerSerializers$IndexedListSerializer.serializeContents(ContainerSerializers.java:189)
at org.codehaus.jackson.map.ser.ContainerSerializers$AsArraySerializer.serialize(ContainerSerializers.java:111)
at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:296)
at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:224)
at org.codehaus.jackson.map.ObjectMapper.writeValue(ObjectMapper.java:925)
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.writeInternal(MappingJacksonHttpMessageConverter.java:153)
이 문제의 원인을 확인하기 위해 추가 정보를 얻을 수있는 방법에 대한 제안? 누구든지 그것을 고치는 방법을 알고 있습니까?
편집 : 프록시 개체에 getHander () 및 기타 get * () 메서드가 있음을 발견했습니다. GRR !! 프록시에서 아무것도 처리하지 않도록 Jackson에게 말할 수있는 방법이 있습니까, 아니면 제가 졸입니까? JSON을 뱉어내는 방법은 항상이 아닌 특정 상황에서만 충돌하기 때문에 이것은 정말 이상합니다. 그럼에도 불구하고 프록시 개체의 get * () 메서드 때문입니다.
곁에 : 프록시는 악합니다. 그들은 Jackson, equals () 및 일반 Java 프로그래밍의 다른 많은 부분을 방해합니다. 나는 Hibernate를 완전히 버리고 싶다 : /
이상적이지는 않지만 @JsonAutoDetect
클래스 수준에서 사용하여 Jackson의 JSON 속성 자동 검색을 비활성화 할 수 있습니다. 이것은 Javassist 항목을 처리하려는 시도 (및 실패)를 방지합니다.
즉, 각 getter에 수동으로 (를 사용하여 @JsonProperty
) 주석을 달아야 하지만 명시 적으로 유지하기 때문에 반드시 나쁜 것은 아닙니다.
최대 절전 프록시 개체를 통한 지연로드와 비슷한 문제가있었습니다. lazyloaded private 속성이있는 클래스에 다음과 같이 주석을 추가하여 문제를 해결했습니다.
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
해당 주석에 JSON 직렬화를 중단하는 프록시 개체의 속성을 추가 할 수 있다고 가정합니다.
가져 오지 않은 지연 객체에 대한 Jackson 직렬화 방지
동일한 오류가 발생했지만 Hibernate와는 관련이 없습니다. 나는 Hibernate와 lazy loading의 경우와 관련이 있다고 생각하는 모든 무서운 제안으로 무서워졌습니다 ... 그러나 내 경우에는 내부 클래스에서 getter / setter가 없기 때문에 오류가 발생하여 BeanSerializer가 직렬화 할 수 없습니다 자료...
getter 및 setter를 추가하면 문제가 해결되었습니다.
그만한 가치가있는 것은 방금 시작된 Jackson Hibernate 모듈 프로젝트 이며,이 프로젝트는이 문제를 해결해야하며 다른 사람들도 해결해야합니다. 프로젝트는 핵심 소스의 일부는 아니지만 Jackson 프로젝트와 관련이 있습니다. 이것은 대부분 더 간단한 릴리스 프로세스를 허용하기위한 것입니다. 모듈 API가 도입 될 때 Jackson 1.7이 필요합니다.
나는 같은 문제가 있었다. 을 사용하고 있는지 확인하십시오 hibernatesession.load()
. 그렇다면 hibernatesession.get()
. 이것은 내 문제를 해결했습니다.
나는 봄의 @RestController
. 내 나머지 컨트롤러 클래스는 스프링 클래스를 사용 JpaRepository
하고 있었고 repository.getOne(id)
메서드 호출을 repository.findOne(id)
문제로 대체하여 사라졌습니다.
이 문제를 해결하기 위해 jackson-datatype-hibernate 모듈을 사용할 수 있습니다. 그것은 나를 위해 일합니다. 참조 : https://github.com/FasterXML/jackson-datatype-hibernate
나도 같은 문제가있어, 여기에 인사말
가져 오지 않은 지연 객체에 대한 Jackson 직렬화 방지
http://blog.pastelstudios.com/2012/03/12/spring-3-1-hibernate-4-jackson-module-hibernate/
https://github.com/nessonqk/jackson-datatype-hibernate
다른 답변과 마찬가지로 문제는 게으른 가져 오기를 수행하기 위해 다 대일 열을 선언하는 것이 었습니다. 즉시 가져 오기로 전환하면 문제가 해결되었습니다. 전에:
@ManyToOne(targetEntity = StatusCode.class, fetch = FetchType.LAZY)
후:
@ManyToOne(targetEntity = StatusCode.class, fetch = FetchType.EAGER)
@JsonIgnoreProperties(value = { "handler", "hibernateLazyInitializer" })
클래스 "Director"에 주석을 사용할 수 있습니다.
최대 절전 모드 관련 속성을 항상 무시하도록 Object.class에 Jackson 믹스 인을 추가 할 수 있습니다. Spring Boot를 사용하는 경우 Application 클래스에 넣으십시오.
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder b = new Jackson2ObjectMapperBuilder();
b.mixIn(Object.class, IgnoreHibernatePropertiesInJackson.class);
return b;
}
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private abstract class IgnoreHibernatePropertiesInJackson{ }
I am New to Jackson API, when i got the "org.codehaus.jackson.map.JsonMappingException: No serializer found for class com.company.project.yourclass" , I added the getter and setter to com.company.project.yourclass, that helped me to use the ObjectMapper's mapper object to write the java object into a flat file.
I faced the same issue and It is really strange that the same code works in few case whereas it failed in some random cases.
I got it fixed by just making sure the proper setter/getter (Making sure the case sensitivity)
I tried @JsonDetect
and
@JsonIgnoreProperties(value = { "handler", "hibernateLazyInitializer" })
Neither of them worked for me. Using a third-party module seemed like a lot of work to me. So I just tried making a get
call on any property of the lazy object before passing to jackson
for serlization. The working code snippet looked something like this :
@RequestMapping(value = "/authenticate", produces = "application/json; charset=utf-8")
@ResponseBody
@Transactional
public Account authenticate(Principal principal) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = (UsernamePasswordAuthenticationToken) principal;
LoggedInUserDetails loggedInUserDetails = (LoggedInUserDetails) usernamePasswordAuthenticationToken.getPrincipal();
User user = userRepository.findOne(loggedInUserDetails.getUserId());
Account account = user.getAccount();
account.getFullName(); //Since, account is lazy giving it directly to jackson for serlization didn't worked & hence, this quick-fix.
return account;
}
Also you can make your domain object Director final. It is not perfect solution but it prevent creating proxy-subclass of you domain class.
'Development Tip' 카테고리의 다른 글
Excel interop 개체를 통해 열 크기를 자동으로 조정하려면 어떻게합니까? (0) | 2020.11.29 |
---|---|
UITextView에 줄 바꿈 추가 (0) | 2020.11.29 |
IOStream의 성능을 향상시키는 방법은 무엇입니까? (0) | 2020.11.28 |
X-Frame-Options : firefox 및 chrome의 ALLOW-FROM (0) | 2020.11.28 |
.pem 파일을 읽고 개인 및 공개 키를 얻는 방법 (0) | 2020.11.28 |