实体类代码如下:
[code="java"]public class Organization {
private int id;
private String name;
private String sn;
private String description;
private Organization parent;
private Set children;
get和set省略
}[/code]
业务实现类:
[code="java"]//删除机构
public void delete(int orgId) {
Organization org =(Organization)this.getHibernateTemplate().load(Organization.class, orgId);
System.out.println(org.getChildren().size());
}[/code]
[color=red][size=large]getchildren和getparent都无法读取,null
调用size导致空指针异常
但能顺利的读取description等属性
配置如下[/size][/color][code="java"]<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
[/code]
[quote]这位兄弟,他的引用都指出来了,这个事物是否关闭有什么关系啊。。。[/quote]
这个引用是CGLib增强后的代理对象,根本就不是原来的对象。
当代码调用org.getChildren().size()的时候会判断是否已经加载,如果lazy="false"的话就没问题,load的时候肯定是已经加载了。
如果lazy="true"(默认)的话,代理对象发现没有加载过,触发sql语句加载children,但是发现session已经关闭了。
哦,我明白了,这个时候因为没有Spring事务的保护,其实已经是Detached的对象了,因为laze="true",所以children是空的。
提醒楼主,默认状态下getHibernateTemplate()中的方法都是会自动关闭session的,如果楼主要学习的话,请直接调用session的方法,而不要太依赖getHibernateTemplate(),如果是要正二八经的开发,请使用Spring的事务配置,给这段代码所在的方法加上事务。
用了spring么?用了的话。你在业务实现类这一级的方法上加事务,在一个事务中,一般配置下,spring会用org.springframework.orm.hibernate3.HibernateTransactionManager,以保证在一个事务中的session一直是开着的。
因为你没有这个事务管理,而getHibernateTemplate().load方法执行完以后,session就自动关掉了。
[code="java"][/code]
改成
[code="java"][/code]
试试
[code="java"]因为你没有这个事务管理,而getHibernateTemplate().load方法执行完以后,session就自动关掉了。[/code]
这位兄弟,他的引用都指出来了,这个事物是否关闭有什么关系啊。。。