2012-07-17 58 views
16

我正在開發Spring MVC項目。我正在使用Hibernate。我想使用AJAX與jQuery從我的Spring控制器中獲取一些JSON。不幸的是,當我實現我的應用程序Gson方法我已經得到了一個錯誤:如何正確轉換特定對象列表爲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類,我用我的春天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; 
} 

EDIT 2

不,我List<Message>對象沒有代理。

+1

這可能是因爲hibernate爲您的對象創建代理。所以參數'List messages'不能處理這些代理。正如你從你的堆棧跟蹤中看到的,你正試圖序列化'org.hibernate.proxy.HibernateProxy'。也許你可以在運行時使用帶有字節碼操作的'cglib'來避免創建代理。 – madhead 2012-07-17 07:49:37

+0

您應該將Hibernate對象映射到常規對象。 – Tomer 2012-07-17 08:24:53

+0

我不得不簡單地創建類似於Hibernate對象但沒有註釋的POJO類嗎? @madhead然而,使用'cglib'似乎是一個矯枉過正的問題。 – woyaru 2012-07-17 08:30:56

回答

25

我解決了我的問題。關於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。

+0

非常感謝woyaru ..我有類似的問題,但通過創建一個自定義的JsonSerializer通過它。 :) – FireAndIce 2013-02-28 05:36:41

2

正如評論中提到的@madhead,這是因爲,根據情況,Hibernate會在您的對象周圍創建代理,這會爲某些方法調用實際的實現,爲其他方法調用實際的實現。因此,你的對象的「實際」類型是HibernateProxy。您可以使用類似於here所述的代碼來訪問您的實施。在你的情況下,你必須爲列表中的每個項目調用「unproxy」方法,將它們放入一個新列表中。

+0

不幸的是我仍然有同樣的錯誤。我已經在我的項目中實現了'unproxy'方法,例如您建議我的方法。 – woyaru 2012-07-17 09:08:13

+0

我意識到我的對象不是'HibernateProxy'的實例。所以'unproxy'方法在我的情況下什麼也不做。我的意思是在這種情況下if(entity!= null && instance instanceof HibernateProxy)'結果是錯誤的。 – woyaru 2012-07-17 09:59:13

0

雖然很老的答案,我想通過創建一個DTO消息與字符串字段將解決的目的。

相關問題