GWT - RPC 传输休眠对象问题

Posted

技术标签:

【中文标题】GWT - RPC 传输休眠对象问题【英文标题】:GWT - RPC transporting Hibernate object issue 【发布时间】:2012-07-25 15:40:44 【问题描述】:

我在通过 GWT 中的 RPC 调用传输一个对象时遇到问题。我在这个项目中使用 Spring MVC 和 Hibernate。

这是实体类:

@Entity
public class Room implements Serializable
    private static final long serialVersionUID = -5924198459524011627L;

    private Long id;
    private String name;
    private String description;

    private Set<Wall> walls = new HashSet<Wall>(0);

    public Room()
    

    public Room(String name, String description)
        this.name = name;
        this.description = description;
    

    public Room(String name, String description, Set<Wall> walls)
        this.name = name;
        this.description = description;
        this.walls = walls;
    

    @Id
    @Column(name = "ROOM_ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() 
        return id;
    
    public void setId(Long id) 
        this.id = id;
    
    public String getName() 
        return name;
    
    public void setName(String name) 
        this.name = name;
    
    public String getDescription() 
        return description;
    
    public void setDescription(String description) 
        this.description = description;
    

    @ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinTable(name = "ROOM_WALL", joinColumns = @JoinColumn(name = "ROOM_ID"),
            inverseJoinColumns = @JoinColumn(name = "WALL_ID"))
    public Set<Wall> getWalls()
        return walls;
       

    public void setWalls(Set<Wall> walls)
        this.walls = walls;
    

这是我的 RoomDAO

@Repository
public class RoomDAO 

    @Autowired
    private HibernateTemplate hibernate;

    public Room get(Long id)
        return hibernate.get(Room.class, id);
    

    public void delete(Room entity)
        hibernate.delete(entity);
    

    public void save(Room entity)
        hibernate.saveOrUpdate(entity);
    

    private Session getCurrentSession()
        return hibernate.getSessionFactory().getCurrentSession();
       

    @SuppressWarnings("unchecked")
    public List<Room> list()
        String queryStr = "from "+Room.class.getSimpleName()+" fetch all properties";
        Query query = getCurrentSession().createQuery(queryStr);
        System.out.println("Room list succesfull");
        return (List<Room>)query.list();
    

    @SuppressWarnings("unchecked")
    public List<Wall> getWalls(Long id)
        String queryStr = "from "+Wall.class.getSimpleName()+" wl join wl.walls ls where ls.id=:"+id;
        Query query = getCurrentSession().createQuery(queryStr);
        System.out.println("Walls list succesfull");
        return (List<Wall>)query.list();
    

这是我得到的错误信息

com.google.gwt.user.client.rpc.SerializationException: Type 'org.hibernate.collection.PersistentSet' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = []
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:619)
    at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:126)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter$ValueWriter$8.write(ServerSerializationStreamWriter.java:153)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeValue(ServerSerializationStreamWriter.java:539)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeClass(ServerSerializationStreamWriter.java:709)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeImpl(ServerSerializationStreamWriter.java:748)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:621)
    at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:126)
    at com.google.gwt.user.client.rpc.core.java.util.Collection_CustomFieldSerializerBase.serialize(Collection_CustomFieldSerializerBase.java:44)
    at com.google.gwt.user.client.rpc.core.java.util.ArrayList_CustomFieldSerializer.serialize(ArrayList_CustomFieldSerializer.java:39)
    at com.google.gwt.user.client.rpc.core.java.util.ArrayList_CustomFieldSerializer.serializeInstance(ArrayList_CustomFieldSerializer.java:51)
    at com.google.gwt.user.client.rpc.core.java.util.ArrayList_CustomFieldSerializer.serializeInstance(ArrayList_CustomFieldSerializer.java:28)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeImpl(ServerSerializationStreamWriter.java:740)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:621)
    at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:126)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter$ValueWriter$8.write(ServerSerializationStreamWriter.java:153)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeValue(ServerSerializationStreamWriter.java:539)
    at com.google.gwt.user.server.rpc.RPC.encodeResponse(RPC.java:616)
    at com.google.gwt.user.server.rpc.RPC.encodeResponseForSuccess(RPC.java:474)
    at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:571)
    at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:551)
    at org.spring4gwt.server.SpringGwtRemoteServiceServlet.processCall(SpringGwtRemoteServiceServlet.java:37)
    at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)
    at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:324)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)

我想问一下这个问题是否是由ManyToMany关系和Set用来映射我的实体之间的关系引起的。因为当我在使用 Set 的地方传输一个没有任何关系(ManyToMany 或 OneToMany 等)的对象时,RPC 调用工作正常。

这可能是用 List 替换 Set 的解决方案吗?我知道 List 对数据库无效,但我不想重建整个项目:D

我发现这些问题可以通过使用 Dozer for ex 来解决。

非常感谢您的回答:)

【问题讨论】:

【参考方案1】:

这是一个已知问题。请查看文章Using GWT with Hibernate 中的为什么 Hibernate 对象在到达浏览器世界时无法理解一章。

【讨论】:

感谢您的回答 :) 我已经检查了可能的解决方案......最后我在服务器端调整了我的 Hibernate 对象,并将它们发送到客户端,而没有不可序列化的对象。所以我解决了不能在服务器端传输的逻辑:)

以上是关于GWT - RPC 传输休眠对象问题的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用啥来传输带有 Hibernate 的 GWT RPC 的分层对象?

与 GWT 客户端和 ASP.NET C# 服务器端的通信/传输协议

使用 GWT 内置的 RPC 序列化/反序列化机制

如何使用 fileUpload 在 GWT 中将文件从客户端传输到服务器

如何在 GWT RPC 中将异常从服务器传递到客户端

在 java 中正确处理类型层次结构的 RPC 机制