考虑一个典型的任务,当我们必须构建巨大的文件报告时,通过滚动来自DB的适当结果。ORM框架是Hibernate。我们知道,有三种方法,如何避免这种模式的OutOfMemoryException:
session.evict(...):
ScrollableResults customers = session.createQuery("from Customers order by id").scroll(ScrollMode.FORWARD_ONLY);while (customers.next()) { Customer customer = (Customer) customers.get(0);addDataToReport(customer);session.evict(customer);}session.clear():
ScrollableResults customers = session.createQuery("from Customers order by id").scroll(ScrollMode.FORWARD_ONLY);int i= 0;while (customers.next()) { Customer = ( customer ) customers.get( 0);addDataToReport(customer);if ( ++i % 1000 == 0) session.clear();}CacheMode.IGNORE:
客户= id").setCacheMode(CacheMode.IGNORE).scroll(ScrollMode.FORWARD_ONLY);( ScrollableResults customers =(客户) customers.get(0);addDataToReport ( Customer );}因此,的问题是:就上述目的而言,这些方法中哪一种更好(从性能上说)?或者可能还有更有效的其他方法?
发布于 2013-04-13 09:51:39
CacheMode.IGNORE与您的问题无关。它大约是二级缓存,而不是会话缓存。CascadeType.DETACH或CascadeType.ALL配置关系,则CascadeType.DETACH不会驱逐相关实体。意思是:
clear()之前的方法是最好的选择:
发布于 2022-07-06 10:51:18
关于evict()和StatelessSession
它们都可以优化内存使用,以防止将整个数据加载到内存中。
主要区别在于,evict()仍然可以从Hibernate特性中获益,如2级缓存、延迟加载等。
而StatelessSession是Hibernate全功能禁用的方式.它依赖于JDBC,它提供了比evict()更好的内存优化,但更适合只读场景(因为StatelessSession方式中的实体需要程序员显式维护)。
在使用它们中的任何一个时,程序员在处理实体的状态、刷新时间、连接和事务创建以及它们的生命周期等时都需要小心。
有关更多细节,请参见以下博客:https://dzone.com/articles/bulk-fetching-hibernate
https://stackoverflow.com/questions/15986374
复制相似问题