如果您有理由继续使用有状态的Session
,您可以考虑使用StatelessSession
。
回调接口
你的DAO类,允许您提供,旨在接受每个实体在列表中,一个接一个的回调接口的实现揭露的方法。
public interface EntityCallback<T> {
boolean doWithEntity(T entity);
}
这里的想法是,你的服务层可以调用上述接口实现一个DAO方法如下:
public <T> void findAll(EntityCallback<T> callback) {
ScrollableResults<T> results = /* get result set*/
int iterations = 0;
while(results.hasNext()) {
iterations++;
T entity = results.next();
if(!callback.doWithEntity(entity)) {
break;
}
if(iterations % 100 == 0) {
session.clear();
iterations = 0;
}
}
results.close();
}
上述方法的好处是,它可以防止泄露任何休眠专用持久性构造到服务层,而不实际将业务逻辑推入数据访问层。
裹的ScrollableResults Autoclosable资源
可能有次它可能只是简单迭代在事务内的服务层的结果。通过在类的周围创建一个包装,你可以利用试用资源。
public class QueryResult<T> implements Iterator<T>, AutoCloseable {
/* add implementation stuffs */
}
然后,服务层里面,你可以用它如下:
try(Iterator<Entity> it = dao.iterator(...)) {
while(it.hasNext()) {
Entity entity = it.next();
}
}
很像findAll(EntityCallback<T>)
方法是如何保持迭代次数的跟踪,你QueryResult
类可以做相同的基于每次打电话给next()
,因此可以按特定间隔自动清除会话。
试用资源方法的好处是,因为它使用JDK7的AutoCloseable
接口,服务层可以简单地将它用作迭代器,而不必关心底层结果集并关闭它。
看起来你可以尝试[StatelessSession](https://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/StatelessSession.html)作为无状态会话不实现第一级缓存和与“会话”相比,重量轻。虽然它有一些限制,如链接中指定的 –
您可以粘贴一段代码片段或示例或链接以供参考吗? – Kathiresa
请参阅** [无状态会话]的第13.3节**(https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html) –