随变混混

美丽是一门技艺

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  2 Posts :: 0 Stories :: 0 Comments :: 0 Trackbacks

2010年10月5日 #

Technorati 标签: ,,,

有很多同学在用使用flex+hibernate做应用开发时都会出现由延迟加载导致的异常:Could not initialize proxy…………….

笔者在使用ibatis2.x做持久层时,也遇到这个问题,究其原因,在于blazeds无法正常序列化Java端返回的代理类。

而hibernate默认会对类属性和集合属性返回代理,在大多数情况下这都是很合理的,即使要在web端访问代理属性,也可以采用openSessionInView模式,将session延伸到web层。但是flex的客户端比较特殊,不宜采取这种做法。针对这个问题,有一些开源的解决方案:dpHibernate,Glead等,但笔者感觉这些框架侵入性太强,不宜采用。

在不引入第三方框架的情况下,可以采取两个办法:1.增加一层Vo类,将类属性和集合属性的代理进行转化,然后与as映射,传给flex端 ,这样序列化是ok的。

2.采用Spring 的aop解决方案,对可能返回无法正常序列化的pojo方法进行拦截。步骤如下:

1.开启@AspectJ

<aop:aspectj-autoproxy/>


2.编写针对具有代理属性类的转化工具类:假如Student类具有多对一的类属性Grade:

public class Student {
	private Long id;
	private Grade grade;
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public Grade getGrade() {
		return grade;
	}
	public void setGrade(Grade grade) {
		this.grade = grade;
	}
}

 

用代码生成器生成StudentConvert.java :

public class StudentConverter {

    public static Student convert2Student(Object sourceObj) {
    	Student source=(Student) sourceObj;
        Student target = new Student(); 
        target.setId(source.getId());
      //Hibernate.initialize(source.getGrade());  可以选择将类或集合代理初始化
       //target.setGrade(source.getGrade());
        return target;
    }

    public static List  convert2StudentList(List oldlist) {
        List newlist= new ArrayList();
        for(Object sourceObj : oldlist) {
        	newlist.add(convert2Student(sourceObj));
        }
        return newlist;
    }
}
3.编写aop的advisor进行环绕通知,假设StudentDao 有两个方法 
Student findById(Long id)
List  findAll();
由代码生成器生成对应的advisor如下 HibernateAdvisor.java :
 
@Aspect
public class HibernateAdvisor {

		//insert aop code  for hibernate
   
///////////////////////////
// Student readme
///////////////////////////
	/**
	 * 必须为final String类型的,注解里要使用的变量只能是静态常量类型的
	 */
	// 切入点定义
	public static final String StudentList = "execution(* com.lai.flex.service.StudentDao.findAll(..))";
	public static final String Student = "execution(* com.lai.flex.service.StudentDao.findBy*(..))";

	@Around(StudentList)
	public List convertStudentList(ProceedingJoinPoint joinPoint) {

		//System.out.println("Convert之前");
		Object[] args = joinPoint.getArgs();
		Object obj = null;
		List newlist= null;
		try {
			obj = joinPoint.proceed(args);
			List old= (List) obj;
			newlist=(StudentConverter.convert2StudentList(oldlist));
		} catch (Throwable e) {
			e.printStackTrace();
		}
		//System.out.println("Convert之后"); // 方法执行后的代理处理
		return newlist;
	}

	@Around(Student)
	public Student convertStudent(ProceedingJoinPoint joinPoint) {

		//System.out.println("Convert之前");
		Object[] args = joinPoint.getArgs();
		Object obj = null;

		Student newsStudent = null;
		try {
			obj = joinPoint.proceed(args);
			newsStudent = StudentConverter.convert2Student(obj);

		} catch (Throwable e) {
			e.printStackTrace();
		}
		//System.out.println("Convert之后"); // 方法执行后的代理处理
		return newsStudent;
	}
	
	// generator-insert-location
  
	

}

最后,由StudentDao方法返回的代理类和集合属性在序列化到flex端之前,都被拦截,进行转化后,可以正常序列化了。
声明:如需转载,请注明作者-hhlai1990@gmail.com  
欢迎大家使用rapid-framework快速开发框架以及rapid-generator代码生成器
http://code.google.com/p/rapid-framework
posted @ 2010-10-05 10:43 随变混混 阅读(666) | 评论 (0)编辑 收藏