17

I am working on Spring MVC project. I am using Hibernate. I want to use AJAX with jQuery to get some JSONs from my Spring Controllers. Unfortunately when I was implementing Gson methods in my application I have got an error:

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

Which adapter I have to use and in which way? The error has occurred on the last line of the method:

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

This is my Message class I am using in my Spring MVC project with 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
}

EDIT

I am wondering: my Message object is proxied or the whole List<Message>? I am getting the list of messages in this way:

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

EDIT 2

No, my List<Message> object isn't proxied.

woyaru
  • 5,344
  • 11
  • 48
  • 89
  • 1
    That's maybe because hibernate creates proxies for your objects. So the parameter `List messages` cannot handle that proxies. As you see from your stacktrace you are trying to serialize `org.hibernate.proxy.HibernateProxy`. Maybe you can use `cglib` with bytecode manipulations in runtime to avoid creating proxies. – madhead Jul 17 '12 at 07:49
  • You should map the Hibernate object to a regular object. – Tomer Jul 17 '12 at 08:24
  • I have to simply create POJO class similar to Hibernate object but without annotations? @madhead However using `cglib` seems to me a overkill. – woyaru Jul 17 '12 at 08:30
  • FYI if `List` was proxified it would not be an instance of `HibernateProxy` but rather of `PersistentCollection`. Beware of what you are testing ;) – Aldian Oct 25 '16 at 14:50

3 Answers3

25

I have resolved my problem. The assumption about HibernateProxy objects seemed to be very probable. However everything has started to work properly when I have read carefully my error. Finally I have registered type adapter in this way:

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

Any my MessageAdapter class looks like:

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

And thats all. Now I can get JSONs in jQuery using AJAX properly.

woyaru
  • 5,344
  • 11
  • 48
  • 89
2

As @madhead mentioned in the comments, this happens because, depending on the situation, Hibernate creates proxies around your object, which will call the actual implementation for some methods, and a "instrumented" one for others. Thus, the "actual" type of your objects are HibernateProxy. You can get access to your implementation by using a code similar to the one described here . In your case, you'd have to call the "unproxy" method for each item in your list, putting them into a new list.

Community
  • 1
  • 1
jpkrohling
  • 13,333
  • 1
  • 33
  • 38
  • Unfortunately I have got still the same error. I have implemented in my project `unproxy` method such as you have suggested me. – woyaru Jul 17 '12 at 09:08
  • I have realized that my objects aren't instances of `HibernateProxy`. So `unproxy` method do nothing in my case. I mean that in this condition `if (entity != null && entity instanceof HibernateProxy)` the result is false. – woyaru Jul 17 '12 at 09:59
0

Though pretty old to answer, I guess by just creating a DTO for Message with String fields would solve the purpose.

raikumardipak
  • 1,049
  • 1
  • 20
  • 35