我想批量从数据库中获取多个Hibernate映射对象。据我所知,目前Hibernate(或我所知的任何Java ORM)都不支持。所以我使用实现此API的RMI编写了一个驱动程序:
interface HibernateBatchDriver extends Remote
{
Serializable [] execute (String [] hqlQueries) throws RemoteException;
}
此API的实现打开针对本地数据库的Hibernate会话,逐个发出查询,批量处理结果,并将它们返回给调用者。这样做的问题是被提取的对象在被发回之后不再有任何Session
附加到它们,因此在稍后从这些对象访问延迟获取的字段结束时没有会话错误。有这个问题的解决方案吗?我不认为Session
对象是可序列化的,否则我也会通过网络发送它们。
答案 0 :(得分:1)
正如@dcernahoschi所提到的,Session
对象是Serializable
,但JDBC连接不是。 Serializable意味着您将某些内容保存到文件中,稍后您将其读取并且它是同一个对象。您无法将JDBC连接保存到文件,也可以稍后从该文件还原。您必须打开一个新的JDBC连接。
因此,即使您可以通过RMI发送会话,您也需要在远程计算机中进行JDBC连接。但是,如果可以在远程计算机中设置会话,那么为什么不在该计算机中执行查询呢?
如果你想通过RMI发送查询结果,那么你需要做的是获取整个对象而不是懒惰地获取。为此,您必须将所有关系定义为在映射中急切获取的关系。
如果您无法将映射更改为eager,则可以选择获取每个对象的“深层”副本并通过RMI发送此对象。创建对象的深层副本需要付出一些努力,但如果您无法将映射更改为急切获取,则这是唯一的解决方案。 这种方法意味着您的接口方法必须更改为:
List[] execute (String [] hqlQueries) throws RemoteException;
方法结果中的每个列表都会保留一个查询提取的结果。
答案 1 :(得分:1)
Hibernate Session对象为Serializable
。底层JDBC连接不是。因此,您可以在序列化之前断开()会话与JDBC连接,并在反序列化后重新连接()它。
不幸的是,如果您需要将会话发送到无法获取新JDBC连接的主机,这对您无济于事。所以唯一的选择是完全加载对象,序列化并将它们发送到远程主机。