web-dev-qa-db-ja.com

Hibernateオブジェクトをシリアル化するときに奇妙なJackson例外がスローされる

ジャクソンは、私が修正する方法を知らない奇妙な例外を投げています。 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)

これを引き起こしている原因を確認するための詳細情報の入手方法に関する提案誰でもそれを修正する方法を知っていますか?

EDIT: getHander()および他のget *()メソッドがプロキシオブジェクトに存在することを発見しました。 GRR !!プロキシで何も処理しないようにジャクソンに伝えることができる方法はありますか、それとも私はソルですか? JSONを吐き出すメソッドは常にではなく特定の状況でのみクラッシュするため、これは本当に奇妙です。それでも、プロキシオブジェクトのget *()メソッドが原因です。

余談:プロキシは悪です。これらは、Jackson、equals()、および通常のJavaプログラミングの他の多くの部分を混乱させます。

61
egervari

理想的ではありませんが、JSONプロパティのJacksonの自動検出を無効にするには、@JsonAutoDetectクラスレベルで。これにより、Javassistスタッフの処理(および失敗)を防ぐことができます。

これは、各ゲッターに手動で注釈を付ける必要があることを意味します(@JsonProperty)、しかしそれは必ずしも悪いことではありません、それは物事を明示的に保つからです。

38
skaffman

Hibernateプロキシオブジェクトを介した遅延読み込みでも同様の問題が発生しました。遅延読み込みされたプライベートプロパティを持つクラスに注釈を付けることで回避しました:

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

JSONシリアル化をそのアノテーションに壊すプロキシオブジェクトにプロパティを追加できると思います。

フェッチされていない遅延オブジェクトでのジャクソンのシリアル化を避ける

70
Claes Mogren

同じエラーが発生しましたが、Hibernateとは関係ありません。私はここですべての恐ろしい提案から怖がりました。これはHibernateと遅延読み込みの場合に関連すると思います...しかし、私の場合は内部クラスにはゲッター/セッターがないためエラーが発生しましたので、BeanSerializerはシリアル化できませんでしたデータ...

ゲッターとセッターを追加することで問題は解決しました。

23
OhadR

価値があるのは、開始したばかりの Jackson Hibernate module プロジェクトです。このプロジェクトはこの問題を解決し、できれば他のプロジェクトも解決するはずです。プロジェクトはJacksonプロジェクトに関連していますが、コアソースの一部ではありません。これは主に、より簡単なリリースプロセスを可能にするためです。 Module APIが導入されているので、Jackson 1.7が必要です。

9
StaxMan

同じ問題がありました。 hibernatesession.load()を使用しているかどうかを確認してください。その場合は、hibernatesession.get()に変換してみてください。これで問題が解決しました。

6
Jaishankararam

Springの_@RestController_から同じエラーメッセージが表示されました。私の残りのコントローラークラスは、スプリングのJpaRepositoryクラスを使用しており、repository.getOne(id)メソッド呼び出しをrepository.findOne(id)に置き換えることで問題はなくなりました。

5
Remis B

Jackson-datatype-hibernateモジュールを使用して、この問題を解決できます。それは私のために働く。参照: https://github.com/FasterXML/jackson-datatype-hibernate

4
Howard
3
Neeson.Z

他の回答と同様に、私にとっての問題は、遅延フェッチを行うために多対一の列を宣言することでした。熱心なフェッチに切り替えると、問題が修正されました。前:

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

後:

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

Object.classにJacksonミックスインを追加して、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{ }
2
alarive

クラス「Director」で@JsonIgnoreProperties(value = { "handler", "hibernateLazyInitializer" })注釈を使用できます

2
atovstonog

_@JsonDetect_を試しました

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

どちらも私にとってはうまくいきませんでした。サードパーティのモジュールを使用することは、私にとって多くの仕事のように思えました。そこで、getに渡してserlizationする前に、遅延オブジェクトのプロパティでjackson呼び出しを行ってみました。動作するコードスニペットは次のようになりました。

_@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;
    }
_
0
coding_idiot

「org.codehaus.jackson.map.JsonMappingException:No serializer found for class com.company.project.yourclass」を取得したとき、私はジャクソンAPIを初めて使用し、ゲッターとセッターをcom.company.project.yourclassに追加しました、ObjectMapperのマッパーオブジェクトを使用してJavaオブジェクトをフラットファイルに書き込むのに役立ちました。

0
Anver Sadhat

私は同じ問題に直面しましたが、ランダムなケースでは失敗したのに対し、同じコードが少数のケースで機能するのは本当に奇妙です。

適切なセッター/ゲッターを確認するだけで修正されました(大文字と小文字の区別を確認する)

0
Badal

また、ドメインオブジェクトをDirectorの最終版にすることもできます。これは完全な解決策ではありませんが、ドメインクラスのプロキシサブクラスを作成できなくなります。

0
DzianisH