急:请教下关于ssh整合中延迟加载是否必要的问题

ljyadbefgh3 2013-02-12 11:23:50
我刚学ssh没多久,没什么经验,对ssh的认识很大程度上还停留在书上的简单应用!
最近朋友让我帮做个网站,因为其中实体关联比较多,所以碰到一些之前没碰过的麻烦!
1、首先说下问题:
现在学习ssh,总会说到延迟加载,即在web.xml中配置,如下

<filter>
<description>
延长hibernate中session的生命周期
</description>
<filter-name>OpenSessionInView</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>OpenSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

然后再在spring里面配置事务,这个应该也是书上或网上常规的配置方式!
延迟加载的好处就不说了,但是问题是,当实体关联比较多的时候,再对实体对象进行修改(常见于update、delete)后存入数据库时经常出现如下错误
a different object with the same identifier value was already associated with the session


2、我现在的解决方式
这个问题我上网搜索,有用的解决方式是重新创建一个新对象,避免出现在session中调用两个相同的对象!大致方式如下:

public LjyPhototype getFreshPhotoType(LjyPhototype photoType){
LjyPhototype photoType2=new LjyPhototype();
if(photoType==null){
return null;
}
if(photoType!=null){
if(photoType.getId()!=null){
photoType2.setId(photoType.getId());
}
}
if(photoType.getLjyAdmin()!=null){
if(photoType.getLjyAdmin().getAdminId()!=null){
photoType2.setLjyAdmin(photoType.getLjyAdmin());
}
}
……
return photoType2;
}

上述方法用在业务层,其中参数是从Struts2中传递过来的,也就是接受后我还要重新创建一个对象(即划分一个新内存)来接受它,如果直接就对struts2传递过来的对象进行操作(例如super.getHibernateTemplate().save(photoType)),就会出现上述的错误:
a different object with the same identifier value was already associated with the session
这种方法第一个很麻烦,当关联对象很多的时候还容易遗漏;第二个程序可读性降低,一个对象我直接操作就可以了,你还让我重新创建一个对象来接受传递过来的对象信息,再保存,看起来特别扭!

3、因此特别想请教各位大虾几个问题:
(1)上述问题是否存在更好的解决方式?
(2)如果觉得我提的问题不清楚(我也觉得说不清,否则就是要贴的代码太多影响各位心情),我就想问下在实际公司的项目中,SSH延迟加载(通过web.xml、spring配置的)是否有市场?还是用其他的方式来解决关联对象值保存和传递的问题!
...全文
220 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
Coder_Jiang 2013-02-14
  • 打赏
  • 举报
回复
引用 5 楼 ljyadbefgh3 的回复:
引用 4 楼 coderjiang 的回复:不敢完全苟同2楼的看法, OpenSessionInView技术的确有2楼所说的问题, 但如果想使用懒加载机制,就要合理的控制session关闭的时机, OpenSessionInView的技术也是为了解决这个问题而诞生的。 至于楼主的异常 a different object with the same ident……
读取信息-》修改信息, 不需要保存,(持久太对象会自动保存) 看下hibernate三种状态吧,瞬时态、持久态和游离态。
ljyadbefgh3 2013-02-14
  • 打赏
  • 举报
回复
引用 4 楼 coderjiang 的回复:
不敢完全苟同2楼的看法, OpenSessionInView技术的确有2楼所说的问题, 但如果想使用懒加载机制,就要合理的控制session关闭的时机, OpenSessionInView的技术也是为了解决这个问题而诞生的。 至于楼主的异常 a different object with the same identifier value was alread……
谢谢,这个异常其实发生在修改方面比较多! 比如我要修改用户个人信息,那首先从数据库读取数据来,修改完后再保存更新后的数据!异常就在保存更新后的数据时出现,当然是在Hibernate配置了关联对象的时候才出现,如果该实体是独立的,保存就肯定没有问题! Hibernate的三种状态我倒还是了解,但是在ssh中,我都是使用spring提供的方法来进行Hibernate的管理,不知道是否合理,虽然书上很多项目都教了如何在SSH中配置延迟加载,但是再深入一些的资料就很少了,所以我也是懂得应用,但是不知道spring如何管理session对象的!
Coder_Jiang 2013-02-13
  • 打赏
  • 举报
回复
不敢完全苟同2楼的看法, OpenSessionInView技术的确有2楼所说的问题, 但如果想使用懒加载机制,就要合理的控制session关闭的时机, OpenSessionInView的技术也是为了解决这个问题而诞生的。 至于楼主的异常 a different object with the same identifier value was already associated with the session 我怀疑楼主是在一个持久态对象上用了session.save方法,楼主可以再温习一下hibernate中对象的三种状态。
ljyadbefgh3 2013-02-12
  • 打赏
  • 举报
回复
引用 2 楼 bao110908 的回复:
不要这么用!而且也不要在 ORM 中建立任何关联! OpenSessionInView 会将数据库连接的使用周期扩张到整个请求和响应过程,如果并发量大的话,会将数据库连接池迅速耗尽。 一般对于数据库操作有以下几个注意点: 1:尽量减少连接的使用时间,什么时候需要用到了再去获取,用完后立即关闭(还给连接池) 2:不要在数据库事务中处理耗时的操作,比如:网……
谢谢2楼兄弟,你的经验太宝贵了! 我的认识很多还停留在书本,但是在用的时候也会发现当在数据库或在Hibernate中按理论标准来设置关联,会增加很多工作量,而且现在业务层写代码时也都考虑数据完整性,自己有过疑虑是否要按照传统标准来设计! 不过尽管有疑虑,但是在数据库设计的时候,我还是喜欢加外键,这样看起来舒服点(本人有点强迫症,呵呵,大概是被老师和一些理论考试虐习惯了),尤其是通过工具自动生成的E-R模型看起来更为规范合理! 一定要好好试试用你的方式来做做
  • 打赏
  • 举报
回复
不要这么用!而且也不要在 ORM 中建立任何关联! OpenSessionInView 会将数据库连接的使用周期扩张到整个请求和响应过程,如果并发量大的话,会将数据库连接池迅速耗尽。 一般对于数据库操作有以下几个注意点: 1:尽量减少连接的使用时间,什么时候需要用到了再去获取,用完后立即关闭(还给连接池) 2:不要在数据库事务中处理耗时的操作,比如:网络 IO、磁盘 IO,以及一些 CPU 高负荷的运算,因为这些操作比较耗时,数据库连接在这段时间内什么事也没做,但是也占用了一个连接资源 3:去除 ORM 中的级联、关联,改为手工查询 4:去除数据库表中的外键约束,数据完整性由业务代码进行控制 5:对于大表,应尽量少地使用 LEFT JOIN 等关联操作。因为数据库服务对于大表的 LEFT JOIN 操作需要进行大量的运算以及内存占用,如果访问量大的话,会使用数据库服务器的系统资源迅速耗尽,建议采用多次查询的方式
ttigerdna 2013-02-12
  • 打赏
  • 举报
回复
延迟加载在某些场合可以提高性能

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧