杰克逊抛出一个奇怪的例外,我不知道如何解决。我正在使用Spring,Hibernate和Jackson。
我已经考虑过延迟加载会导致问题,但我已采取措施告诉杰克逊不要按如下方式处理各种属性:
@JsonIgnoreProperties({ "sentMessages", "receivedMessages", "educationFacility" })
public class Director extends UserAccount implements EducationFacilityUser {
....
}
我也为所有其他UserAccount子类做了同样的事情。
这是抛出的异常:
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!有什么办法我可以告诉杰克逊不要在代理上处理任何事情,或者我是谁?这真的很奇怪,因为吐出JSON的方法只会在某些情况下崩溃,而不是一直崩溃。尽管如此,这是由于代理对象上的get *()方法。
除此之外:代理是邪恶的。它们破坏了Jackson,equals()和常规Java编程的许多其他部分。我很想完全放弃Hibernate:/
答案 0 :(得分:69)
我在通过hibernate代理对象进行延迟加载时遇到了类似的问题。通过使用以下命令注释具有lazyloaded私有属性的类来解决它:
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
我假设您可以在代理对象上添加将JSON序列化分解为该批注的属性。
答案 1 :(得分:38)
这并不理想,但您可以在班级使用@JsonAutoDetect
禁用Jackson自动发现的JSON属性。这可以防止它试图处理Javassist的东西(并且失败)。
这意味着您必须手动注释每个getter(使用@JsonProperty
),但这不一定是坏事,因为它可以使事情明确。
答案 2 :(得分:23)
我得到了同样的错误,但与Hibernate无关。我从所有可怕的建议中得到了惊吓,我认为在Hibernate和延迟加载的情况下相关...... 但是,在我的情况下我得到了错误,因为在内部类中我没有getter / setter,所以BeanSerializer无法序列化数据......
添加吸气剂&塞特斯解决了这个问题。
答案 3 :(得分:9)
对于它的价值,有Jackson Hibernate module项目刚刚开始,哪个应该解决这个问题,希望其他人也是如此。 项目与杰克逊项目有关,虽然不是核心资源的一部分。这主要是为了让发布过程更简单;当模块API被引入时,它将需要Jackson 1.7。
答案 4 :(得分:6)
我遇到了同样的问题。看看您是否使用hibernatesession.load()
。如果是,请尝试转换为hibernatesession.get()
。这解决了我的问题。
答案 5 :(得分:5)
我从spring @RestController
收到了同样的错误消息。我的其他控制器类使用的是spring JpaRepository
类,并且用repository.getOne(id)
替换repository.findOne(id)
方法调用问题已经消失。
答案 6 :(得分:4)
您可以使用jackson-datatype-hibernate模块来解决此问题。它对我有用。 参考:https://github.com/FasterXML/jackson-datatype-hibernate
答案 7 :(得分:3)
我遇到了同样的问题,致敬是
Avoid Jackson serialization on non fetched lazy objects
http://blog.pastelstudios.com/2012/03/12/spring-3-1-hibernate-4-jackson-module-hibernate/
答案 8 :(得分:3)
与其他答案类似,我的问题是声明多对一列进行延迟抓取。切换到急切提取修复了问题。 之前:
@ManyToOne(targetEntity = StatusCode.class, fetch = FetchType.LAZY)
后:
@ManyToOne(targetEntity = StatusCode.class, fetch = FetchType.EAGER)
答案 9 :(得分:2)
您可以在班级“导演”上使用@JsonIgnoreProperties(value = { "handler", "hibernateLazyInitializer" })
注释
答案 10 :(得分:2)
您可以在Object.class上添加Jackson mixin以始终忽略与hibernate相关的属性。如果您使用的是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{ }
答案 11 :(得分:0)
我是Jackson API的新手,当我收到“org.codehaus.jackson.map.JsonMappingException:没有找到类com.company.project.yourclass的序列化程序”时,我将getter和setter添加到了com.company。 project.yourclass,帮助我使用ObjectMapper的mapper对象将java对象写入平面文件。
答案 12 :(得分:0)
我遇到了同样的问题,同样的代码在少数情况下工作,而在某些随机情况下失败,这真的很奇怪。
我通过确保正确的setter / getter(确保区分大小写)来解决问题
答案 13 :(得分:0)
我尝试了@JsonDetect
和
@JsonIgnoreProperties(value = { "handler", "hibernateLazyInitializer" })
他们都没有为我工作。使用第三方模块对我来说似乎很多工作。所以我只是尝试对惰性对象的任何属性进行get
调用,然后传递给jackson
进行serlization。工作代码段看起来像这样:
@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;
}
答案 14 :(得分:0)
此外,您可以将您的域对象Director设为最终版。它不是完美的解决方案,但它会阻止您创建域类的代理子类。