我正在开发Spring MVC项目。我正在使用Hibernate。我想使用AJAX和jQuery从我的Spring Controller中获取一些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的Spring MVC项目中使用的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>
对象未被代理。
答案 0 :(得分: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。
答案 1 :(得分:2)
正如评论中提到的@madhead,这是因为,根据情况,Hibernate会在您的对象周围创建代理,这将调用某些方法的实际实现,并为其他方法调用“已检测”。因此,对象的“实际”类型是HibernateProxy。您可以使用类似于here所述的代码来访问您的实现。在您的情况下,您必须为列表中的每个项目调用“unproxy”方法,将它们放入新列表中。
答案 2 :(得分:0)
虽然很难回答,但我想通过为字符串字段创建DTO来解决目的。