hibernate+spring mvc,解决hibernate对象懒加载,json序列化失败

合集下载

SpringMVC+Spring+Hibernate框架整合原理,作用及使用方法

SpringMVC+Spring+Hibernate框架整合原理,作用及使用方法

SpringMVC+Spring+Hibernate框架整合原理,作⽤及使⽤⽅法SSM框架是spring MVC ,spring和mybatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,controller层,service层,DAO层四层使⽤spring MVC负责请求的转发和视图管理spring实现业务对象管理,mybatis作为数据对象的持久化引擎原理:SpringMVC:1.客户端发送请求到DispacherServlet(分发器)2.由DispacherServlet控制器查询HanderMapping,找到处理请求的Controller3.Controller调⽤业务逻辑处理后,返回ModelAndView4.DispacherSerclet查询视图解析器,找到ModelAndView指定的视图5.视图负责将结果显⽰到客户端Spring:我们平时开发接触最多的估计就是IOC容器,它可以装载bean(也就是我们中的类,当然也包括service dao⾥⾯的),有了这个机制,我们就不⽤在每次使⽤这个类的时候为它初始化,很少看到关键字new。

另外spring的aop,事务管理等等都是我们经常⽤到的。

Mybatis:mybatis是对jdbc的封装,它让数据库底层操作变的透明。

mybatis的操作都是围绕⼀个sqlSessionFactory实例展开的。

mybatis通过配置⽂件关联到各实体类的Mapper⽂件,Mapper⽂件中配置了每个类对数据库所需进⾏的sql语句映射。

在每次与数据库交互时,通过sqlSessionFactory拿到⼀个sqlSession,再执⾏sql命令。

使⽤⽅法:要完成⼀个功能:1. 先写实体类entity,定义对象的属性,(可以参照数据库中表的字段来设置,数据库的设计应该在所有编码开始之前)。

2. 写Mapper.xml(Mybatis),其中定义你的功能,对应要对数据库进⾏的那些操作,⽐如 insert、selectAll、selectByKey、delete、update等。

hibernate中fetch=FetchType.LAZY懒加载失败处理方法

hibernate中fetch=FetchType.LAZY懒加载失败处理方法

hibernate中fetch=ZY懒加载失败处理⽅法对这种懒加载问题,最后的做法是利⽤Spring提供的⼀个针对Hibernate的⼀个⽀持类,其主要意思是在发起⼀个页⾯请求时打开Hibernate的Session,⼀直保持这个Session,使得Hibernate的Session的⽣命周期变长,直到这个请求结束,具体是通过⼀个Filter来实现的。

那么,如果现在我们想⽤Hibernate懒加载特性,⼜想⽤延长session的⽣命周期,知道将数据提到页⾯显⽰(经过action层),那么我们就得在web.xml⽂件中增加以下配置:<!-- 配置Spring的⽤于解决懒加载问题的过滤器 --><filter><filter-name>OpenSessionInViewFilter</filter-name><filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class></filter><filter-mapping><filter-name>OpenSessionInViewFilter</filter-name><url-pattern>*.action</url-pattern></filter-mapping> 注:1)OpenSessionInViewFilter为过滤器名字,*.action表⽰拦截所有的action,也可以 /* 2)⾮ web 页⾯请求(如定时任务)可以按下⾯的⽅式进⾏处理(Hibernate.initialize(Object proxy) ⽅法强制加载这样就相当于动态改变为lazy=fals)/*** @Author masl - 2017/9/28 14:22* @param setRepaymentId* @param initSubs :是否初始化关联表数据* @return*/@Overridepublic SetRepayment findSetRepaymentById(Integer setRepaymentId, boolean initSubs) {SetRepayment setRepayment = null;if (setRepaymentId != null) {setRepayment = setRepaymentDao.get(setRepaymentId);if (setRepayment != null && initSubs) {Hibernate.initialize(setRepayment.getSetIncomes());}return setRepayment;}return null;}总结以上所述是⼩编给⼤家介绍的hibernate 中 fetch=ZY 懒加载失败处理⽅法,希望对⼤家有所帮助,如果⼤家有任何疑问请给我留⾔,⼩编会及时回复⼤家的。

spring和Hibernate的工作原理

spring和Hibernate的工作原理

spring工作原理spring的最大作用ioc/di,将类与类的依赖关系写在配置文件中,程序在运行时根据配置文件动态加载依赖的类,降低的类与类之间的藕合度。

它的原理是在applicationContext.xml加入bean标签,在bean标签中通过class属性说明具体类名、通过property标签说明该类的属性名、通过constructor-args说明构造子的参数。

其一切都是返射,当通过applicationContext.getBean("id名称")得到一个类实例时,就是以bean标签的类名、属性名、构造子的参数为准,通过反射实例对象,唤起对象的set方法设置属性值、通过构造子的newInstance实例化得到对象。

正因为spring一切都是反射,反射比直接调用的处理速度慢,所以这也是spring 的一个问题。

spring第二大作用就是aop,其机理来自于代理模式,代理模式有三个角色分别是通用接口、代理、真实对象代理、真实对象实现的是同一接口,将真实对象作为代理的一个属性,向客户端公开的是代理,当客户端调用代理的方法时,代理找到真实对象,调用真实对象方法,在调用之前之后提供相关的服务,如事务、安全、日志。

其名称分别是代理、真实对象、装备、关切点、连接点。

spring也不是帮我们去new的,因为new这个东西实在是不好,spring是通过反射的机制帮助我们实现的,建议你去看看java的反射和动态代理,这个对你spring乃至以后的学习都是非常有用的!spring是一个非常优秀的框架,他的官方强烈推荐使用面向接口编程,非常好的思想!方便以后程序的扩展!有兴趣真的可以好好的研究下spring,你会知道大师级们写代码就是不一样!Hibernate工作原理学习过程是首先看看java反射的概念,然后学学AOP原理:1.读取并解析配置文件2.读取并解析映射信息,创建SessionFactory3.打开Sesssion4.创建事务Transation5.持久化操作6.提交事务7.关闭Session8.关闭SesstionFactory为什么要用:1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。

hibernate_03_懒加载和二级缓存

hibernate_03_懒加载和二级缓存

关联关系的懒加载
1.session.load懒加载。 2.one-to-one(元素)懒加载: 必需同时满足下面三个条件时才能实现懒加载 (主表不能有constrained=true,所以主表没有懒加载) lazy!=false 2)constrained=true 3)fetch=select 3.one-to-many (元素)懒加载:1)lazy!=false 2)fetch=select 4.many-to-one (元素) :1)lazy!=false 2)fetch=select 5.many-to-many (元素) :1)lazy!=false 2)fetch=select 6.能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭 时,访问这些懒加载对象(代理对象)的属性(getId和getClass除外) hibernate会初始化这些代理,或用Hibernate.initialize(proxy)来初始化代 理对象;当相关联的session关闭后,再访问懒加载的对象将出现异常。
7、 需要说明的是:lazy的默认值为true,fetch的默认值为select.
Load方法的使用精髓:



Load方法不会命中数据库。且必须要确定数据库中存在此记录时 才可以使用load方法。这让load方法变成了鸡肋。 但要注意,任何一个方法的设计都是有用的。正所谓天生我才必 有用是也。 如果仅是为了数据绑定、设置数据之间的关系,则没有必要命中 数据库,此时load方法的效率就比get高,因为load方法不会命中 数据库,但却可以设置上关系。 如: • Person p = session.load(Person.class,11); • Car c = session.load(Car.class,1001); • p.getCars().add(c); • session.save(p);

如何解决hibernate一对多注解懒加载失效问题

如何解决hibernate一对多注解懒加载失效问题

如何解决hibernate⼀对多注解懒加载失效问题⽬录hibernate⼀对多注解懒加载失效经排查,问题出在controller这边解决⽅法Hibernate懒加载异常说明及其解决懒加载异常出现的原因解决⽅案1解决⽅案2解决⽅案3hibernate⼀对多注解懒加载失效在House类⾥有关联HouseInfo,设置了懒加载但是页⾯ajax返回还是有HouseInfos的数据。

经排查,问题出在controller这边@response注解启⽤jackson框架对House进⾏解析然后调⽤了每个属性的get⽅法,⾃然houseInfos的懒加载就失效了解决⽅法给houseInfos字段加上@JsonIgnore注解忽略json解析Hibernate懒加载异常说明及其解决在集成ssh2三⼤框架的时候很容易就会造成懒加载异常,通常显⽰的错误信息是:zyInitializationException: could not initialize proxy - no Session懒加载异常出现的原因我们在Action中调⽤Service中的⽅法,⽅法中开始时open session,当调⽤结束后close session,例如类User中有⼀个Department属性,我们使⽤Hibernate查询⼀个User时,hibernate默认是懒加载的,此时查询出的User不会把Department中所有的信息查询出来。

当session 关闭后我们在Result中(例如在jsp中打印)使⽤到了Department的name属性时就会出现懒加载异常。

解决⽅案1不⽤懒加载(不推荐)解决⽅案2我们不在⽅法结束的时候关闭session,在执⾏完Action Result之后,通过过滤器关闭session,具体如下:使⽤OpenSessionInViewFilter解决解决懒加载问题,在web.xml中配置:<!-- openSessionInViewFilter,改过滤器在view渲染时始终开启session,⼀劳永逸解决hibernate的懒加载问题,该过滤器必须配置在struts2过滤器之前,⼀般推荐使⽤(由于性能问题,在view渲染时始终开启session)--> <filter> <filter-name>openSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>openSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>解决⽅案3例如涉及三个类分别为Survey、Page、Question类,三个类的关联关系class Survey{ private Long id; private List<Page> pageList=new ArrayList<Page>();}class Page{ private Long id; private List<Question> questionList=new ArrayList<Question>();}class Question{ private Long id;}⽅法是强⾏在service层⾯是初始化代理对象.public Survey getSurveyWithChildren(Long sid){ Survey s = surveyDao.getEntity(sid); //强⾏初始化pages和questions集合 for(Page p : s.getPages()){ p.getQuestions().size(); } return s;}以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。

关于延迟加载(lazy)和强制加载

关于延迟加载(lazy)和强制加载
信息,那么自动加载address的特性就显得多余,并且造成了极大的性能浪费。为了获得user 的性别属性,我们可能还要同时从数据库中读取数条无用的地址数据,这导致了大量无谓的系统开销。
延迟加载特性的出现,正是为了解决这个问题。所谓延迟加载,就是在需要数据的时候,才真正执行数据加载操作。
对于我们这里的user对象的加载过程,也就意味着,加载user对象时只针对其本身的属性, 而当我们需要获取user对象所关联的address信息时(如执行user.getAddresses时),才
TUser user = (TUser)session.load(TUser.class,new Integer(1));
VO经过Hibernate进行处理,就变成了PO。上面的示例代码session.save(user)中,我们把一个VO “user”传递给Hibernate的Session.save方法进行保存。在save方法中,Hibernate对其进
TUser user =(TUser)userList.get(0);
System.out.println("User name => "+user.getName());
Set hset = user.getAddresses();
session.close();//关闭Session
这里有个问题,如果我们采用了延迟加载机制,但希望在一些情况下,实现非延迟加载时的功能,也就是说,我们希望在Session关闭后,依然允许操作user的addresses
属性。如,为了向View层提供数据,我们必须提供一个完整的User对象,包含其所关联的address信息,而这个User对象必须在Session关闭之后仍然可以使用。

浅谈Hibernate三种状态

浅谈Hibernate三种状态

浅谈Hibernate三种状态在当今,利用JA V A语言开发软件系统时,Hibernate框架技术因其面向对象、可提高开发效率、更好的可移植性和简化了持久层的开发等特点得到了越来越多的应用。

Hibernate是一个优秀的持久化框架,其在应用程序开发时有三中状态即:transient(临时状态),persistent(持久化状态)以及detached(游离状态)。

本文以实例的方式来探讨一下这三种状态。

标签:JA V A;Hibernate;持久化一、概念在我们讨论如何实现Hibernate三种状态前,先看一看这三种状态都代表什么。

(1)临时状态(transient):当一个对象在内存中孤立存在,不与数据库中的数据有任何关联关系时,那么这个对象就称为临时对象。

(2)持久化状态(persistent):当一个对象与一个Session相关联时,就变成持久化对象。

通俗一些就是对数据和程序状态的保持。

数据持久化往往也就意味着将内存中的数据保存到磁盘上加以固化,而持久化的实现过程则大多通过各种关系型数据库来完成的。

(3)游离状态(detached):在这个Session被关闭的同时,这个对象也会脱离持久化状态,就变成游离状态,可以被应用程序的任何层自由使用,例如可以做与表示层打交道的数据舆对象。

在我们了解了Hibenate的三种状态之后,可以通过一个图来了解这三种状态之间的关系。

如图1所示二、利用实例了解三种狀态(一)临时状态用例(Test Transient)session=HibernateUtil.openSession();session.beginTransaction();User user=new User();user.setUsername(“aaa”);user.setPassword(“aaa”);user.setBorn(new Date());session.save(user);session.getTransaction().commit();根据以上用例我们可以发现user就是一个Transient(临时状态),此时user 并没有被session进行托管,即在session的缓存中还不存在user这个对象,当执行完save方法后,此时user被session托管,并且数据库中存在了该对象user 就变成了一个Persistent(持久化对象)。

Hibernate懒加载详解

Hibernate懒加载详解

Hibernate懒加载详解懒加载为Hibernate中比较常用的特性之一,下面我们具体来了解下懒加载的原理和注重事项 Load()办法的懒加载原理在Hibernate中,查询办法有两个,分离是get()和load(),这两种办法的不同就是load()拥有懒加载的特性。

Load()办法就是在查询某一条数据的时候并不会挺直将这条数据以指定对象的形式来返回,而是在你真正需要用法该对象里面的一些属性的时候才会去数据库拜访并得到数据。

他的益处就是可以削减程序本身由于与数据库常见的交互造成的处理速度缓慢。

以一个Person类做例子,我们写一个查询的办法如下: public ic vo query(int id){ Session session=null;y{ session=HibernateUtil.getSession(); Personperson=(Person) session.load(Person.class, id);//System.out.print(person.getName()); }ch(HibernateException ){ ex.printStackTrace(); }finally{ if(session!=null){ ses sion.close(); } 然后在Hibernate配置文件中添加以下属性property name= hibernate.show_sql true /property 这条属性的作用为将Hibernate运行时产生的每一条SQL语句都打印出来运行上述办法后,我们并没有看到Hibernate打印任何查询语句,这时我们可以将注释的语句重新调回归,让他打印查询到的person的name。

这时我们可以看到Hibernate产生的查询语句并看到person的name属性。

这就是懒加载了。

那么在Hibernate懒加载的时候,返回的对象是空的吗?答案是否定的,我们可以通过打印person.getClass()办法来验证,打印出来的结果并不是null,而是一个Person后面加了一堆很惊奇的字符的类。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第二种方法(推荐): 在一对多的关的时候就会过滤掉这个对象:
Java 代码
1. @OneToMany(cascade = CascadeType.ALL, fetch = ZY, mappedBy = " user") 2. @JsonIgnore 3. public Set<Log> getLogs() { 4. return this.logs; 5. } 6. 7. public void setLogs(Set<Log> logs) { 8. this.logs = logs; 9. }
客户端抛出 zyInitializationException 异常。通过查询资料和摸索整理出三 种解决方法: 第一种:(推荐) 在 web.xml 中加入:
Xml 代码
1. <filter> 2. <filter-name>openSession</filter-name> 3. <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInView Filter</filter-class> 4. <init-param> 5. <param-name>singleSession</param-name> 6. <param-value>false</param-value> 7. </init-param> 8. </filter> 9. <filter-mapping> 10. <filter-name>openSession</filter-name> 11. <url-pattern>/*</url-pattern> 12. </filter-mapping>
hibernate+spring mvc,解决 hibernate 对象懒加载, json 序 列化失败
分类: springMvc2014-06-25 13:3124 人阅读评论(0)收藏举报
在使用 Spring MVC 时,@ResponseBody 注解的方法返回一个有懒加载对象的时候出现 了异常,以登录为例:
Java 代码
1. @RequestMapping("login") 2. @ResponseBody 3. public Object login(@RequestParam String username,@RequestParam String pas sword){ 4. List<User> list=userDAO.findByUsername(username); 5. if(list.size()>0){ 6. User user=list.get(0); 7. if(user.getPassword().equals(password)){ 8. return new Result(user, "操作成功", true); 9. }else{ 10. return new Result(null, "密码错误", true); 11. } 12. }else{ 13. return new Result(null, "用户未注册", false); 14. } 15. }
第三种方式: 把 fetch 模式配置成“FetchType.EAGER”,这样的方式可以解决问题,但是这样的方式会强 制提取一对多关系中的数据,生成很多无用数据,也会增加系统负担,所以不建议采用。
Java 代码
1. @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "user") 2. public Set<Log> getLogs() { 3. return this.logs; 4. } 5. 6. public void setLogs(Set<Log> logs) { 7. this.logs = logs; 8. }
这样返回的 Spring mvc 返回的 Json 串也包含一对多关系中的对象,不过都是空的。
Js 代码
1. {"message":"操作成功","results":{"language":null,"id":"402881e6421e40b6014 21e4111c60001","type":null,"extra":null,"time":null,"username":"wanggang", "msg":null,"password":"138333","tag":null,"tel":null,"qq":null,"email":nul l,"gender":null,"lat":null,"lang":null,"point":null,"openid":null,"city":n ull,"photo":null,"notes":[],"chatsForUserTwoId":[],"attentionsForUserId": [],"attentionsForAttentionUserId":[],"logs":[],"chatsForUserOneId":[],"com mentsForNoteId":[],"commentsForUserId":[]},"success":true}
相关文档
最新文档