web-dev-qa-db-ja.com

特定のオブジェクトのリストをGsonに適切に変換する方法は?

私はSpringMVCプロジェクトに取り組んでいます。私はHibernateを使用しています。 AJAXをjQueryで使用して、SpringコントローラーからいくつかのJSONを取得したい。残念ながら、アプリケーションにGsonメソッドを実装しているときに、エラーが発生しました。

Java.lang.UnsupportedOperationException: Attempted to serialize Java.lang.Class: 
org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter?

どのアダプターをどのように使用する必要がありますか?メソッドの最後の行でエラーが発生しました:

public String messagesToJson(List<Message> messages) {
    Gson gson = new Gson();     
    List<Message> synchronizedMessages = Collections.synchronizedList(messages);
    return gson.toJson(synchronizedMessages, ArrayList.class);
}

これは、Hibernateを使用したSpringMVCプロジェクトで使用しているMessageクラスです。

@Entity
@Table(name = "MESSAGES", schema = "PUBLIC", catalog = "PUBLIC")
public class Message implements Java.io.Serializable {

    private static final long serialVersionUID = 1L;
    private int messageId;
    private User users;
    private String message;
    private Date date;

    //Constructor, getters, setters, toString
}

[〜#〜]編集[〜#〜]

私は疑問に思っています:私のMessageオブジェクトはプロキシされていますか、それともList<Message>全体ですか?私はこの方法でメッセージのリストを取得しています:

public List<Message> findAllUserMessages(String username) {
    Query query = entityManager.createQuery("from Message where username = :username order by date desc")
            .setParameter("username", username);

    @SuppressWarnings("unchecked")
    List<Message> messages = query.getResultList();
    return messages;
}

編集2

いいえ、私のList<Message>オブジェクトはプロキシされていません。

17
woyaru

問題を解決しました。 HibernateProxyオブジェクトに関する仮定は非常に可能性が高いようでした。しかし、エラーを注意深く読んだとき、すべてが正しく機能し始めました。最後に、この方法でタイプアダプタを登録しました。

public String messagesToJson(List<Message> messages) {  
    GsonBuilder gsonBuilder = new GsonBuilder();
    Gson gson = gsonBuilder.registerTypeAdapter(Message.class, new MessageAdapter()).create();
    return gson.toJson(messages);
}   

私のMessageAdapterクラスは次のようになります。

public class MessageAdapter implements JsonSerializer<Message> {

    @Override
    public JsonElement serialize(Message message, Type type, JsonSerializationContext jsc) {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("message_id", message.getMessageId());
        jsonObject.addProperty("message", message.getMessage());
        jsonObject.addProperty("user", message.getUsers().getUsername());
        jsonObject.addProperty("date", message.getDate().toString());
        return jsonObject;      
    }
}

そしてそれがすべてです。これで、AJAXを適切に使用して、jQueryでJSONを取得できます。

25
woyaru

@madheadがコメントで述べたように、これは、状況に応じて、Hibernateがオブジェクトの周囲にプロキシを作成し、一部のメソッドの実際の実装を呼び出し、他のメソッドの「インストルメント化された」実装を呼び出すために発生します。したがって、オブジェクトの「実際の」タイプはHibernateProxyです。説明されているものと同様のコードを使用して、実装にアクセスできます ここ 。あなたの場合、リスト内の各アイテムに対して「unproxy」メソッドを呼び出して、それらを新しいリストに入れる必要があります。

2
jpkrohling

答えるのはかなり古いですが、文字列フィールドを使用してメッセージのDTOを作成するだけで、目的が解決すると思います。

0
raikumardipak