Как правильно преобразовать Список конкретных объектов в Gson? - программирование
Подтвердить что ты не робот

Как правильно преобразовать Список конкретных объектов в Gson?

Я работаю над проектом Spring MVC. Я использую Hibernate. Я хочу использовать AJAX с jQuery, чтобы получить некоторые JSON от моих контроллеров Spring. К сожалению, когда я применял методы 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);
}

Это мой класс Message, который я использую в моем проекте Spring MVC с Hibernate:

@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> не проксирован.

4b9b3361

Ответ 1

Я решил свою проблему. Предположение о объектах 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;      
    }
}

И все. Теперь я могу получить JSON в jQuery, используя AJAX правильно.

Ответ 2

Как упоминалось в комментариях @madhead, это происходит потому, что в зависимости от ситуации Hibernate создает прокси-серверы вокруг вашего объекта, который будет вызывать фактическую реализацию для некоторых методов и "инструмент" для других. Таким образом, "фактическим" типом ваших объектов является HibernateProxy. Вы можете получить доступ к своей реализации, используя код, подобный описанному здесь. В вашем случае вам придется вызывать метод "unproxy" для каждого элемента в вашем списке, помещая их в новый список.

Ответ 3

Хотя довольно старый, чтобы ответить, я думаю, просто создав DTO для полей Message with String, вы решите цель.