Mar*_* K. 10 java orm remoting jpa lazy-loading
我遇到了像大多数尝试使用ORM进行远程处理的人一样的LazyLoading异常.在大多数情况下,切换到急切的提取解决了问题(延迟加载/非原子查询/线程安全/ n + 1问题......).但是,如果你正在处理一个非常大的对象图,那么急切的提取也会有缺点.
在大多数用例中不需要加载整个对象图.加载需要的更多数据(或从数据库加载数据并提取所需的子集)感觉很糟糕.
那么有什么替代方法可以解决这类问题(在运行时)?
我见过:
我想了很多其他的方式.也许通用投影white./black listning是一个解决方案.
Idea(黑名单):使用提取操作的边界定义类名列表.如果属性匹配并且它是惰性的,则删除惰性(CGLIB)代理并使用null填充该值.否则,简单地防止获取(并将值保留为null).因此,我们可以在DAO中设置明确的界限.
示例:ProductDao.findByName("Soap",Boundaries.BLACKLIST,"Category, Discount")
最后两个参数也可以绑定到Boundaries对象中.
Idea(白名单):与黑名单一样,但您必须声明属性应加载到白名单中.
您如何看待这样的解决方案?(可能的问题,限制,优点......)我应该如何在java中编写这个?也许通过AOP来匹配DAO方法(因为我能够在那里修改cglib代理行为)?
你可以摆脱所有的收藏品NamedQueries而不是使用.我们在一个项目(EJB + Swing)中使用了这种方法,并且它工作得很好 - 因此您可以确定要获取的确切数据.NamedQueries是普通查询,将它们想象为PreparedStatement-s.我们的想法是不使用查询创建/检索/更新/删除单个对象.我们的想法是您通过查询获取收藏集.例如,不是映射@ManyToMany List,而是定义一个获取该列表的NamedQuery.因此,您可以单独获取集合数据,并且只在您需要时,而不是自动获取.
对传输的对象使用自定义代理(使用CGLIB) - 每当引用一个集合(通过其getter),尝试retreival,并捕获任何内容LazyInitializationException并为所请求的数据调用服务器层.
就像前一个一样,但只使用集合的代理,就像Hibernate在需要延迟初始化时代理它们一样.
另外,看一下Value List Handler模式 - 可能很有用.
(hibernate.max_fetch_depth如果适合您的情况,您也可以使用(如果使用Hibernate)上述组合.)
| 归档时间: |
|
| 查看次数: |
6079 次 |
| 最近记录: |