Month: August 2008

Hibernate: 设A引用了B,则删A后可能要evict(A.getB())

Hibernate: 设A引用了B,如果要先取A删A再取B删B,则删A后可能要evict(A.getB()),才能顺利删除B 否则,就会报错:a different object with the same identifier value was already associated with the session 原理是这样的:        第一步将A从数据库中取出时,它引用的B也从数据库中取出,两者同时成为持久化对象。A删除后,B是处于Session中的持久化对象       第二步中又显式地将B从数据库中取出,加上第一步中取出的B,Session里就有两个B了。这时侯如果删B,就会报上面所说的那种错误。        因此,应该在删除A后立即将它引用了的B从Session中清除掉。即:        A   =  Session.load(A);        Session.delete(A);        Session.evict(A.getB());        Session.delete(B); =============================================== 注意:evict()并不会级联,除非设置了相应的cascade 也就是说,如果B引用了C, evict(B)时不会自动evict(C) 看官方文档: This operation cascades to associated instances if the association is mapped with cascade="all" or cascade="all-delete-orphan". 

[ibatis]执行resultMap里配置的子select时,是否生成了新的connection

查询对象:一棵树状Bean 环境:Spring Template + JdbcTransactionManager + ibatis 发现:    1.执行树型查询时,ibatis中ExternalTransaction类曾多次执行connection.close()方法    2.Spring Template 生成的Transaction实例并不是ExternalTransaction,而是UserProvidedTransaction。看来Spring Template在执行一次查询的时候使用两种Transaction,一类由Spring模板维护,它的生命周期为整个session,一个session里只有一个;另一类用作具体的db request,每做一次query就生成一个    3. Spring Template 使用的 SqlMapExecutor是SqlMapSession,这个类还继承了SqlMapTransactionManager接口,使得每次执行查询后都会调用ExternalTransaction来关闭一下Connection   (SqlMapExecutorDelegate的autoEndTransaction()方法)     4. 不管有没有Spring Template,ibatis同一个session内的每个request都要用一个新的Connection! 也就是树型Bean千万不能用ibatis来做查询的框架!

Spring + Hibernate:hibernate配置文件不在classes下,怎么办?

    配置hibernate.cfg.xml时,如果这个文件的路径在classes目录之上的某个目录,如web/WEB-INF/hibernate.cfg.xml,咋办?    我开始试着将sessionFactory的configuration值配成  ../hibernate.cfg.xml,不行; 配成 file:///../hibernate.cfg.xml,也不行;看了下源代码,这个东西根本不支持用".."表示的相对路径。    configuration的类型是org.springframework.core.io.Resource,于是我们只好这样解决:写一个类实现Resource接口,在这个类中定义hibernate文件路径为web/WEB-INF/hiberate.cfg.xml,然后将类装配成Bean,并注入到sessionFactory里。    spring正常情况下用的Resource类是org.springframework.core.io.FileSystemResource类,因此我们的实现类应将FileSystemResource类当作我们的 实现类的 一个成员变量,将这个成员变量的path设为 web/hibernate.cfg.xml的绝对路径(要利用java.io.File API),并通过这个成员来实现Resource接口要求实现的方法。     通过这种办法,最后测试通过。