GWTでRPC呼び出しを介して1つのオブジェクトを転送する際に問題が発生しました。このプロジェクトでは、SpringMVCと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)
この問題の原因が、エンティティ間の関係をマップするために使用される多対多の関係とセットが原因であるかどうかを確認したいと思います。Setを使用する関係のないオブジェクト(ManyToManyやOneToManyなど)を転送する場合、RPC呼び出しは正常に機能するためです。
Set by Listを置き換えるソリューションでしょうか?リストはデータベースには効果的ではないことは知っていますが、プロジェクト全体を再構築したくありません:D
これらの問題は、例としてDozerを使用することで解決できることがわかりました。
ご回答ありがとうございます:)