Étrange exception Jackson étant jeté lors de la sérialisation objet Mise en veille prolongée

StackOverflow https://stackoverflow.com/questions/4362104

Question

Jackson est de lancer une exception bizarre que je ne sais pas comment résoudre. J'utilise Spring, Hibernate et Jackson.

Je l'ai déjà considéré que de chargement paresseux est à l'origine du problème, mais je l'ai pris des mesures pour dire Jackson pour traiter diverses propriétés pas comme suit:

@JsonIgnoreProperties({ "sentMessages", "receivedMessages", "educationFacility" })
public class Director extends UserAccount implements EducationFacilityUser {
   ....
}

Je l'ai fait la même chose pour toutes les autres sous-classes de useraccount ainsi.

Voici l'exception levée:

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)

Suggestions sur la façon dont je peux obtenir plus d'informations pour voir ce qui cause? Quelqu'un sait comment y remédier?

EDIT: J'ai découvert que les méthodes getHander () et d'autres get * () sont disponibles sur l'objet proxy. GRR !! Est-il possible que je peux dire Jackson de ne pas quoi que ce soit sur le processus proxy, ou suis-je SÖL? Ceci est vraiment bizarre parce que la méthode qui crache sur la tombe en panne JSON que dans certaines circonstances, pas tout le temps. Néanmoins, il est dû aux méthodes get * () sur l'objet proxy.

En plus: Les proxies sont mal. Ils bouleversent Jackson, equals () et beaucoup d'autres parties de la programmation régulière Java. Je suis tenté de fossé Hibernate tout à fait: /

Était-ce utile?

La solution

Il est pas idéal, mais vous pouvez désactiver Jackson auto-découverte de propriétés JSON, en utilisant @JsonAutoDetect au niveau de la classe. Cela empêcherait d'essayer de gérer les choses Javassist (et à défaut).

Cela signifie que vous avez alors annoter chaque getter manuellement (avec @JsonProperty), mais ce n'est pas nécessairement une mauvaise chose, car il garde les choses explicites.

Autres conseils

J'ai eu un problème similaire avec le chargement paresseux via l'objet proxy veille prolongée. Vous avez autour en annotant la classe ayant des propriétés privées lazyloaded avec:

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

Je suppose que vous pouvez ajouter les propriétés de votre objet proxy qui brise la sérialisation JSON à cette annotation.

éviter sérialisation Jackson sur des objets paresseux non récupérés

i obtenu la même erreur, mais sans relation avec Hibernate. Je me suis fait peur ici de toutes les suggestions effrayantes, qui je pense pertinentes en cas de mise en veille prolongée et le chargement paresseux ... Cependant, dans mon cas, je suis l'erreur puisque dans une classe interne je n'avais pas getters / setters, de sorte que le BeanSerializer ne pouvait pas sérialiser les données ...

Ajout getters et setters ont résolu le problème.

Pour ce que ça vaut la peine, il est Jackson projet qui vient de commencer, et qui devrait résoudre ce problème et nous espérons que d'autres. Le projet est lié au projet Jackson, bien que ne faisant pas partie de la source principale. Ceci est la plupart du temps pour permettre processus de libération plus simple; il faudra Jackson 1.7 comme c'est lorsque l'API du module est en cours d'introduction.

J'ai eu le même problème. Voyez si vous utilisez hibernatesession.load(). Si oui, essayez de le convertir à hibernatesession.get(). Cela a résolu mon problème.

J'ai eu le même message d'erreur de la @RestController de printemps. Mon repos classe contrôleur utilisait la classe JpaRepository de printemps et en remplaçant appel de méthode repository.getOne(id) avec le problème de repository.findOne(id) était parti.

Vous pouvez utiliser le module jackson-type de données-veille prolongée pour résoudre ce problème. Il fonctionne pour moi. Référence: https://github.com/FasterXML/jackson-datatype-hibernate

Comme dans d'autres réponses, le problème pour moi déclarais un grand nombre à une colonne pour faire paresseux fetching. Le passage à fetching désireux résolu le problème. Avant:

@ManyToOne(targetEntity = StatusCode.class, fetch = FetchType.LAZY)

Après:

@ManyToOne(targetEntity = StatusCode.class, fetch = FetchType.EAGER)

Vous pouvez utiliser l'annotation @JsonIgnoreProperties(value = { "handler", "hibernateLazyInitializer" }) votre classe "directeur"

Vous pouvez ajouter un mixin Jackson sur Object.class toujours ignorer les propriétés liées-mise en veille prolongée. Si vous utilisez Spring Boot mis dans votre classe d'application:

@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
    Jackson2ObjectMapperBuilder b = new Jackson2ObjectMapperBuilder();
    b.mixIn(Object.class, IgnoreHibernatePropertiesInJackson.class);
    return b;
}


@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private abstract class IgnoreHibernatePropertiesInJackson{ }

Je suis nouveau à l'API Jackson, quand je suis arrivé le « org.codehaus.jackson.map.JsonMappingException: Aucun sérialiseur trouvé pour com.company.project.yourclass de classe », j'ai ajouté le getter et setter à com.company. project.yourclass, qui m'a aidé à utiliser l'objet mappeur du ObjectMapper pour écrire l'objet java dans un fichier plat.

Je fait face à la même question et il est vraiment étrange que le même code fonctionne dans quelques cas alors qu'il a échoué dans certains cas au hasard.

Je l'ai réparé simplement en vous assurant le setter / getter approprié (Veiller à ce que la sensibilité à la casse)

J'ai essayé @JsonDetect et

@JsonIgnoreProperties(value = { "handler", "hibernateLazyInitializer" })

Aucun d'entre eux a travaillé pour moi. L'utilisation d'un module tiers semblait beaucoup de travail pour moi. Donc, je viens d'essayer de faire un appel get sur une propriété de l'objet paresseux avant de passer à jackson pour serlization. Le code de travail Snippet avait l'air quelque chose comme ceci:

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

Vous pouvez aussi faire votre objet domaine directeur final. Il n'est pas la solution parfaite, mais elle empêche la création de sous-classe proxy vous classe de domaine.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top