- 浏览: 182921 次
- 性别:
- 来自: 威海
文章分类
- 全部博客 (96)
- javascript (9)
- css (4)
- java (5)
- xml (1)
- dhtml (5)
- ajax (0)
- spring (0)
- 版本控制 (3)
- tomcat (0)
- web技术 (9)
- eclipse插件 (3)
- flex (9)
- android (3)
- 性能测试 (1)
- flash (4)
- Academic (4)
- EJB (2)
- JSF (0)
- ExtJS (2)
- ROR (9)
- linux (2)
- oracle (2)
- wtc (1)
- extjs4 (1)
- servlet (1)
- postgreSQL (3)
- OS (1)
- 线程 (1)
- unity3d (4)
- html (1)
- rvm (0)
最新评论
-
zxjlwt:
学习了。素人派http://surenpi.com
eclipse插件开发手记之编辑器上下文菜单 -
176170847:
你也遇到了?请问你怎么解决的啊?
flex swfloader 加载swf帧频变化 -
Kim_T:
我的完全没用 , 不知道怎么回事? 俩个地方我都设置了
svn忽略无关文件thumbs.db等 -
yiyanwan77:
babydeed 写道挺好的 建议弄成 chm格式的 呵呵 呵 ...
EXTJS4开发指南中文翻译 -
babydeed:
挺好的 建议弄成 chm格式的 呵呵
EXTJS4开发指南中文翻译
- 问题简单描述
项目中后台使用hibernate实现的jpa作为持久层,当blazeds解析返回数据包含未加载项时,触发了延迟加载动作,而此时事物已经结束,于是抛出session关闭异常。
- 解决思路
后台通过jpa返回的数据结果其实为动态代理创建的该类型的子类,调用这些对象的get方法时,动态代理子类的包装壳判断是否加载了数据(通过查看hibernate源码,可以得知有个initialized属性标记),如果没有,则查询该项。因此,只要避免转换时触发加载动作就可以解决该问题,简单想来有以下几种方案:
- aop切到最外的service层,得到返回结果,递归遍历属性,判断是否加载了属性(基本属性不存在这个问题)-注意,即使属性未加载,该属性值并不为空,而是一个代理对象),如果没有加载则想办法使其返回空(考虑过使用动态代理的方式,未能解决)
- 还是用aop,得到返回结果后,创建新的实例返回,依然要判断是否加载,如果已加载则返回真实值 (因为得到的对象为动态代理类,在对象为集合的时候获取实际类有点困难,我暂未能获知该途径,若有知情人,还望不吝赐教)
- 上面两种方案都需要增加递归遍历过程,对性能时有影响的,特别时第二种,所有属性都要重新创建,开销比较大。因此最佳方案应该时直接修改blazeds的源码,返回结果处理时,再用上述第一种方案的思路。
- 实现
因为项目时间上的压力,考虑从第一种方案入手,在实际解决的过程中仍然遇到了重重困难,无数次断点调试后发现了了如下规律:如果返回值为集合,则获取到的类名为PersistenceSet(实际上并非所有集合都是用Set代理 ),而如果为单个对象则类名中含有_$$_javasis..等内容(该规则与动态代理的实现有关),后来查看hibernate源码,发现代理其实为PersistentCollection或HibernateProxy接口的实现类,大部分问题都解决了,但是最后遇到子项加载父项时,如果直接置空属性,则将更新(此时session已经关闭,但实际上更新确成功了,这个现象一直没弄明白 ),尝试用动态代理解决,没有成功。最后,迫于项目时间压力,暂时再该期使用了第二种实现方式:
org.hibernate.collection.*
PersistentSet extends AbstractPersistentCollection implements java.util.Set AbstractPersistentCollection implements Serializable, PersistentCollection PersistentArrayHolder extends AbstractPersistentCollection PersistentBag extends AbstractPersistentCollection implements List PersistentElementHolder extends AbstractPersistentCollection PersistentIdentifierBag extends AbstractPersistentCollection implements List PersistentIndexedElementHolder extends AbstractPersistentCollection PersistentList extends AbstractPersistentCollection implements List PersistentListElementHolder extends PersistentIndexedElementHolder PersistentMap extends AbstractPersistentCollection implements Map PersistentMapElementHolder extends PersistentIndexedElementHolder PersistentSet extends AbstractPersistentCollection implements java.util.Set PersistentSortedMap extends PersistentMap implements SortedMap PersistentSortedSet extends PersistentSet implements SortedSet
LazyAspect.java
import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.beanutils.PropertyUtils; import org.apache.log4j.Logger; import org.aspectj.lang.ProceedingJoinPoint; import org.hibernate.collection.PersistentCollection; import org.hibernate.proxy.HibernateProxy; /** * 解决使用延迟加载配置,且service层返回时该项未加载时,blazeds抛出session关闭的问题 * * @author 王逸群 * @date 2011-10-8 */ public class LazyAspect { private static Logger log = Logger.getLogger(LazyAspect.class); public Object doAround(ProceedingJoinPoint pjp) throws Throwable { try { Object retVal = pjp.proceed(); Object safeObject = safeCopy(retVal); return safeObject; } catch (Exception e) { e.printStackTrace(); throw e; } } /** * 不触发延迟加载的深度拷贝 * * @param obj * 拷贝对象 * @return * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException * @throws InstantiationException */ public Object safeCopy(Object obj) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException { return _safeCopy(obj, new HashMap<Object, Object>()); } /** * 不触发延迟加载的深度拷贝 * * @param obj * 拷贝对象 * @param copiedMap * @return * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException * @throws InstantiationException */ @SuppressWarnings({ "rawtypes", "unchecked" }) private Object _safeCopy(Object obj, Map<Object, Object> copiedMap) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException { // 基本类型不可能为代理,直接返回 if (isPrimitive(obj)) { return obj; } // 如果已经解析,直接从map中获取 if (copiedMap.containsKey(obj)) { return copiedMap.get(obj); } Class clazz = obj.getClass(); // Collection对象 if (obj instanceof Collection) { Collection $collection = null; // PersistentCollection 代理 if (obj instanceof PersistentCollection) { PersistentCollection $persistentCollection = (PersistentCollection) obj; // 已经加载字段 if ($persistentCollection.wasInitialized()) { if ($persistentCollection instanceof Set) { //暂无法获取集合实际类 $collection = new HashSet(); } else if ($persistentCollection instanceof List) { //暂无法获取集合实际类 $collection = new ArrayList(); } } // 未加载 else { copiedMap.put(obj, null); return null; } } // 非PersistentCollection代理集合 else { $collection = (Collection) obj.getClass().newInstance(); } Iterator itr = ((Collection) obj).iterator(); if (itr != null) while (itr.hasNext()) { $collection.add(_safeCopy(itr.next(), copiedMap)); } copiedMap.put(obj, $collection); return $collection; } // Map else if (obj instanceof Map) { Map $map = null; Map map = (Map) obj; // 代理 if (obj instanceof PersistentCollection) { PersistentCollection $persistentCollection = (PersistentCollection) obj; // 已加载 if ($persistentCollection.wasInitialized()) { //暂无法获取集合实际类 $map = new HashMap(); } // 未加载 else { copiedMap.put(obj, null); return null; } } // 非代理对象 else { $map = (Map) obj.getClass().newInstance(); } for (Object ele : map.keySet()) { $map.put(ele, _safeCopy(map.get(ele), copiedMap)); } copiedMap.put(obj, $map); return $map; } // 数组 else if (clazz.isArray()) { int len = Array.getLength(obj); if (len > 0) { String arrClassName=clazz.getName(); String className=arrClassName.substring(arrClassName.indexOf("L")+1,arrClassName.length()-1); // 注意,这里创建的实例非Array Object $arr = Array.newInstance(Class.forName(className), len); for (int i = 0; i < len; i++) { Array.set($arr, i, _safeCopy(Array.get(obj, i), copiedMap)); } copiedMap.put(obj, $arr); return $arr; } else { copiedMap.put(obj, null); return null; } } // 代理 if (obj instanceof HibernateProxy) { HibernateProxy proxy = (HibernateProxy) obj; // 已加载 if (!proxy.getHibernateLazyInitializer().isUninitialized()) { Object $obj = _safeCopy(proxy.getHibernateLazyInitializer() .getImplementation(), copiedMap); copiedMap.put(obj, $obj); return $obj; } // 未加载 else { copiedMap.put(obj, null); return null; } } // 普通类 else { Object $obj = obj.getClass().newInstance(); copiedMap.put(obj, $obj); // 解析属性 Field[] fields = obj.getClass().getDeclaredFields(); for (Field field : fields) { String subFieldName = field.getName(); Object fieldValue = null; // 类中可能有不可读属性(指非标准setter,getter访问方式),比如public static if(PropertyUtils.isReadable(obj, subFieldName)){ fieldValue = PropertyUtils.getProperty(obj, subFieldName); } // 属性值为空或者无法读取的不处理 if (fieldValue != null) { PropertyUtils.setProperty($obj, subFieldName, _safeCopy(fieldValue, copiedMap)); } } return $obj; } } /** * 是否为基本类型,注意,与jdk api中的isPrimitive规则不同 * * @param obj * @return */ public boolean isPrimitive(Object obj) { if (obj == null) { return true; } Class clazz = obj.getClass(); if (clazz.isPrimitive()) { return true; } String className = clazz.getName(); return className.indexOf("java") == 0 && (!(obj instanceof Collection)) && (!(obj instanceof Map)) && (!clazz.isArray()); } }
发表评论
-
flex mx:image 在vbox中设置mxHeight依然占位
2012-09-09 16:21 1218<mx:VBox > <m ... -
flash同一个图层创建的按钮无法响应事件
2012-07-30 22:40 882遇到个怪现象,flash一个图层中有多个元素,其中一个做成了按 ... -
flex swfloader 加载swf帧频变化
2012-07-30 22:37 881求解 -
flex FormItem
2011-09-16 16:06 755FormItem831.FormItemSkin832.con ... -
Flex Module静态方法
2011-09-03 15:27 1085在java中使用静态方法提供api是很自然的事情,但在Flex ... -
Flex的静态变量
2011-09-03 15:18 1778主程序App.mxml Module1:A.mxml M ... -
flex 特效
2010-09-17 15:51 1041公司第四个产品大体功能已经开发出来了,接下来的工作很大一 ... -
Flex Cairngorm
2009-08-22 17:22 1180我学Flex Cairngorm-1,Cairngorm概览 ... -
ANT
2009-02-18 16:37 1680ANT 关键字: ant ... -
iframe多帧交互
2009-01-16 14:08 7771:同源策略 2:top指向顶级窗口 3:self==wind ... -
iframe总结
2009-01-12 11:23 1644IFrame语法小全 IFrame语法小全 IFrame可以 ... -
自定义标签
2009-01-08 08:34 1238标准JSP标签是用来调用JavaBean组件的操作,处理定向请 ... -
写自定义标签时标记attribute里rtexprvalue的用法
2009-01-06 09:03 1033写自定义标签时标记attribute里rtexprvalue的 ... -
JavaScript Core Index
2009-01-05 20:21 816JavaScript Core Index Below ... -
Aptana使用入门一:Code Assist
2009-01-05 20:15 2396Aptana使用入门一:Code Assist 2008-03 ... -
32款实用源码编辑器一览
2009-01-05 20:12 384732款实用源码编辑器一览(一) 编译:四眼天兔 原文出 ...
相关推荐
此项目是spring+hibernate+JPA+BoneCP的大整合。所用的技术比较多,如Spring的IOC,AOP,Transactiion,Annotation,Spring_JUnit_Test及Log4j;Hibernate的JPA Annotation;BoneCP的数据库连接测等。是很好的学习资料...
SpringMVC+springAOP+spring security+Hibernate整合实例代码,包含框架jar包
系统日志 记录用户访问监控异常信息 系统缓存管理 将redis的操作可视化,提供对redis的基本操作 Sql监控 采用 druid 监控数据库访问性能 技术栈 基础框架:Spring Boot 2.1.0.RELEASE 持久层框架:Spring boot Jpa ...
内容概要:springboot+拦截器+aop+自定义注解+本地线程实现统一接口日志记录,记录下接口所在模块、接口描述、接口请求参数、接口返回参数、接口请求时间以及接口耗时用于接口优化,接口记录参数以及操作人防止使用...
开发工具:IDEA 开发环境:jdk1.8 项目框架:springboot+jpa+aop 通过注解和aop切面自动切换数据源
aopalliance-1.0.0+aspectjrt+aspectjweaver spring开发框架必备jar包
毕业设计,基于SpringBoot+JPA+Bootstrap开发的图书馆座位占座预约系统,内含Java完整源代码,数据库脚本 基于Springboot+FreeMarker+JPA图书馆座位占座预约系统设计毕业源码案例设计 开发软件:Eclipse或者Idea +...
Spring+proxool+hibernate+struts2+aop整合的完整_Jar包
基于springboot + jpa + Erupt后台框架开发的综合签到打卡系统,支持人脸识别(百度云),指纹识别(本地指纹仪+websocket),签到数据展示,签到情况微信推送。前台上,PC端选择用主流Vue框架[另一位同学完成]、...
aopalliance.jar + aspectjrt.jar + aspectjweaver.jar + spring-aop-3.2.5.RELEASE.jar 【面向spring切面AOP编程的所有jar包集合,可做成用户库User library】
完整的Spring2_0AOP+myeclipse6+事例+工程源码.rar
基于springsecurity+springmvc+spring+hibernate的权限管理系统,实现资源、用户、权限、角色的增删改查,角色-资源管理,用户-角色管理等基础功能,可以作为springmvc+spring+hibernate的增删改查入门项目,也可以...
Spring4.0+Hibernate4.0+Struts2.3整合案例:实现增删改查。... 可以解决办法是:当方法不需要事务支持的时候,使用 Session session = sessionFactory.openSession()来获得Session对象,问题解决!
此资源为我个人毕业设计系统,商城系统源码,包含数据库设计,系统分析,技术(Spring MVC AOP)+MyBatis+Ajax+JavaScript
支持 hibernate spring junit aop的jar包,亲测可用,友友们欢迎下载~~~~
Spring+proxool+hibernate+struts2+aop整合的完整的简单项目
偌大的一个csdn竟然都没有发现一个完整的整合版flex,spring,hibernate。无奈之下自己经过一个半的努力实现了flex调用springAOP管理的java方法,项目中也有我写好的hibernate方法。
这是在做一个物流平台,一批项目:门户网站,配货系统,个人网站,二批,三排请关注我的更新,JAR包可以找我要(qq:438312413),目前只完成登录,权限出步验证(filter,后面会采用spring aop来实现细力度控制,可以...
现在的结构是,Struts负责显示层,Hibernate负责持久层,Spring负责中间的业务层,另外,由于Spring使用的依赖注射以及AOP(面向方面编程),所以它的这种内部模式非常优秀,以至于Spring自己也实现了一个使用依赖注射...
spring中AOP切面编程所需要的jar包完整版,网上资源很少 这四个jar包是我整理后发出的