我个人对openJPA的一些困惑!

我不知道最近openJPA人们使用的多不多,但是我第一次使用的时候感觉还可以。但是在多组合查询的时候感觉还是得写很多HQL语句。不懂在这方面有没有高手能够给我一个提示呢。

openJPA的另外一个不太理解的就是它的延迟加载的问题。我第一次用的时候不太懂,在标间关联的地方设置了

@ManyToOne(cascade = { CascadeType.REFRESH }, fetch = FetchType.LAZY ) @JoinColumn(name = "depart_id") private Depart depart;

其中这是我设置的admin 表与depart表之间的多对一的关联,我希望取出某个admin的信息的时候,也要知道他所在的部门,当我在页面要显示admin.depart.depart_name的时候出现了错误:

could not initialize proxy - the owning Session was closed

当时我不太理解,为什么说我的代理没有初始化,会话已经关闭。然而再去查找一些资料终于明白了他的一些机制。

首先引用一位网上一位朋友的关于lazy方面的见解。我觉得他说的挺全面的。

延迟初始化错误是运用Hibernate开发项目时最常见的错误。如果对一个类或者集合配置了延迟检索策略,那么必须当代理类实例或代理集合处于持久化状态(即处于Session范围内)时,才能初始化它。如果在游离状态时才初始化它,就会产生延迟初始化错误。下面把Customer.hbm.xml文件的<class>元素的lazy属性设为true,表示使用延迟检索策略: <class name="mypack.Customer" table="CUSTOMERS" lazy="true"> 当执行Session的load()方法时,Hibernate不会立即执行查询CUSTOMERS表的select语句,仅仅返回Customer类的代理类的实例,这个代理类具由以下特征:(1) 由Hibernate在运行时动态生成,它扩展了Customer类,因此它继承了Customer类的所有属性和方法,但它的实现对于应用程序是透明的。(2) 当Hibernate创建Customer代理类实例时,仅仅初始化了它的OID属性,其他属性都为null,因此这个代理类实例占用的内存很少。(3)当应用程序第一次访问Customer代理类实例时(例如调用customer.getXXX()或customer.setXXX()方法), Hibernate会初始化代理类实例,在初始化过程中执行select语句,真正从数据库中加载Customer对象的所有数据。但有个例外,那就是当应用程序访问Customer代理类实例的getId()方法时,Hibernate不会初始化代理类实例,因为在创建代理类实例时OID就存在了,不必到数据库中去查询。

也就是说当我执行hql: from Admin a 时,由于设置了could not initialize proxy - the owning Session was closed ,他在load()的时候并不是返回与admin关联的depart的一个实例,我们再取值getXXX()的时候没有得到值,它仅仅是初始化了一个setId,仅仅getId不会为空,其他的均取道的值是空值,是因为我们提供了延迟加载。当我们要getXX()其他属性时,由于它的session关闭了,所以才会抛出异常:could not initialize proxy - the owning Session was closed 解决的办法我是把它的延迟加载could not initialize proxy - the owning Session was closed给去掉了,原因是我每次取出admin表的内容的时候都要知道它在depart表的的位置。但是不懂这样做好不好。还是希望高手给我解释一下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值