??xml version="1.0" encoding="utf-8" standalone="yes"?>日韩一级片在线观看,国产成人免费9x9x人网站视频 ,久久99精品视频一区97http://www.aygfsteel.com/HappyJava/category/28898.htmlq福人生(J2EE)zh-cnThu, 10 Jan 2008 23:13:33 GMTThu, 10 Jan 2008 23:13:33 GMT60异常:could not initialize proxy - the owning Session was closedhttp://www.aygfsteel.com/HappyJava/articles/174438.html李徏?/dc:creator>李徏?/author>Thu, 10 Jan 2008 13:04:00 GMThttp://www.aygfsteel.com/HappyJava/articles/174438.htmlhttp://www.aygfsteel.com/HappyJava/comments/174438.htmlhttp://www.aygfsteel.com/HappyJava/articles/174438.html#Feedback0http://www.aygfsteel.com/HappyJava/comments/commentRss/174438.htmlhttp://www.aygfsteel.com/HappyJava/services/trackbacks/174438.html其实q个异常写的非常之清楚,是?x)话关闭Q无法对Hibernate实体q行操作。造成q样的情冉|很多Q什么书写错误啊Q逻辑错误啊?/p>

但就此说一下关于lazy机制Q?/p>

延迟初始化错误是q用Hibernate开发项目时最常见的错误。如果对一个类或者集合配|了(jin)延迟(g)索策略,那么必须当代理类实例或代理集合处于持久化状态(卛_?/font>Session范围内)(j)Ӟ才能初始化它。如果在游离状态时才初始化它,׃(x)产生延迟初始化错误?br />
下面把Customer.hbm.xml文g?lt;class>元素的lazy属性设为trueQ表CZ用gq检索策略:(x)

<class name="mypack.Customer" table="CUSTOMERS" lazy="true">

当执?/font>Session的load()Ҏ(gu)ӞHibernate不会(x)立即执行查询CUSTOMERS表的select语句Q仅仅返回Customercȝ代理cȝ实例Q这个代理类L(fng)以下特征Q?br />
Q?Q?由Hibernate在运行时动态生成,它扩展了(jin)Customerc,因此它(h)承了(jin)Customercȝ所有属性和Ҏ(gu)Q但它的实现对于应用E序是透明的?br /> Q?Q?当Hibernate创徏Customer代理cd例时Q仅仅初始化?jin)它的OID属性,其他属性都为nullQ因此这个代理类实例占用的内存很?br /> Q?Q当应用E序W一ơ访问Customer代理cd例时Q例如调用customer.getXXX()或customer.setXXX()Ҏ(gu)Q, Hibernate?x)初始化代理cd例,在初始化q程中执行select语句Q真正从数据库中加蝲Customer对象的所有数据。但有个例外Q那是当应用程序访问Customer代理cd例的getId()Ҏ(gu)ӞHibernate不会(x)初始化代理类实例Q因为在创徏代理cd例时OID存在了(jin)Q不必到数据库中L询?br />
提示QHibernate采用CGLIB工具来生成持久化cȝ代理cRCGLIB是一个功能强大的Java字节码生成工P它能够在E序q行时动态生成扩?JavacL者实现Java接口的代理类。关于CGLIB的更多知识,请参考:(x)http://cglib.sourceforge.net/?br />
以下代码先通过
Session的load()Ҏ(gu)加蝲Customer对象Q然后访问它的name属性:(x)

tx =
session.beginTransaction();
Customer customer=(Customer)
session.load(Customer.class,new Long(1));
customer.getName();
tx.commit();

在运?/font>session.load()Ҏ(gu)时Hibernate不执行Q何select语句Q仅仅返回Customercȝ代理cȝ实例Q它的OID?Q这是由load()Ҏ(gu)的第二个参数指定的。当应用E序调用customer.getName()Ҏ(gu)ӞHibernate?x)初始化Customer代理cd例,从数据库中加载Customer对象的数据,执行以下select语句Q?br />
select * from CUSTOMERS where ID=1;
select * from ORDERS where CUSTOMER_ID=1;

?lt;class>元素的lazy属性ؓ(f)trueQ会(x)影响
Session的load()Ҏ(gu)的各U运行时行ؓ(f)Q下面D例说明?br />
1Q如果加载的Customer对象在数据库中不存在Q?/font>Session的load()Ҏ(gu)不会(x)抛出异常Q只有当q行customer.getName()Ҏ(gu)时才?x)抛Z下异常:(x)

ERROR LazyInitializer:63
- Exception initializing proxy
net.sf.hibernate.ObjectNotFoundException: No row with the given identifier exists: 1, of class:
mypack.Customer

2Q如果在整个
Session范围内,应用E序没有讉KqCustomer对象Q那么Customer代理cȝ实例一直不?x)被初始化,Hibernate不会(x)执行Mselect语句。以下代码试囑֜关闭Session后访问Customer游离对象Q?br />
tx =
session.beginTransaction();
Customer customer=(Customer)
session.load(Customer.class,new Long(1));
tx.commit();
session.close();
customer.getName();

׃引用变量customer引用的Customer代理cȝ实例?/font>Session范围内始l没有被初始化,因此在执行customer.getName()Ҏ(gu)ӞHibernate?x)抛Z下异常:(x)

ERROR LazyInitializer:63
- Exception initializing proxy
net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed

由此可见QCustomer代理cȝ实例只有在当?/font>Session范围内才能被初始化?br />
3Qnet.sf.hibernate.Hibernatecȝ
initialize()?rn)态方法用于在Session范围内显式初始化代理cd例,isInitialized()Ҏ(gu)用于判断代理cd例是否已l被初始化。例如:(x)

tx =
session.beginTransaction();
Customer customer=(Customer)
session.load(Customer.class,new Long(1));
if(!Hibernate.isInitialized(customer))
Hibernate.
initialize(customer);
tx.commit();
session.close();
customer.getName();

以上代码?/font>Session范围内通过Hibernatecȝinitialize()Ҏ(gu)昑ּ初始化了(jin)Customer代理cd例,因此?/font>Session关闭后,可以正常讉KCustomer游离对象?br />
4Q当应用E序讉K代理cd例的getId()Ҏ(gu)Ӟ不会(x)触发Hibernate初始化代理类实例的行为,例如Q?br />
tx =
session.beginTransaction();
Customer customer=(Customer)
session.load(Customer.class,new Long(1));
customer.getId();
tx.commit();
session.close();
customer.getName();

当应用程序访问customer.getId()Ҏ(gu)Ӟ该方法直接返回Customer代理cd例的OID|无需查询数据库。由于引用变?customer始终引用的是没有被初始化的Customer代理cd例,因此?/font>Session关闭后再执行customer.getName()Ҏ(gu)Q?Hibernate?x)抛Z下异常:(x)

ERROR LazyInitializer:63 - Exception initializing proxy
net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed

 

解决Ҏ(gu)Q?/font>

׃hibernate采用?jin)lazy=true,q样当你用hibernate查询?q回实际为利用cglib增强的代理类,但其q没有实际填?当你在前?利用它来取?getXXX)?q时Hibernate才会(x)到数据库执行查询,q填充对?但此时如果和q个代理cȝ关的session已关闭掉,׃(x)产生U错?
在做一对多Ӟ有时?x)出?could not initialize proxy - clothe owning Session was sed,q个好像是hibernate的缓存问?问题解决:需要在<many-to-one>里设|lazy="false". 但有可能?x)引发另一个异常叫

failed to lazily initialize a collection of role: XXXXXXXX, no session or session was closed

此异常解x(chng)案请察看本h博客Q?a >http://hi.baidu.com/kekemao1Q的Hibernate异常中的《failed to lazily initialize a collection of role异常?br />
?
解决Ҏ(gu):在web.xml中加?br /> <filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>
     org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
    </filter-class>
</filter
<filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>*.do</url-pattern>
</filter-mapping>
可以了(jin);

参考了(jin):
Hibernate与gq加载:(x)

Hibernate对象关系映射提供延迟的与非gq的对象初始化。非延迟加蝲在读取一个对象的时候会(x)与q个对象所有相关的其他对象一赯取出来。这有时?x)导致成癄Q如果不是成千的话)(j)select语句在读取对象的时候执行。这个问题有时出现在使用双向关系的时候,l常?x)导致整个数据库都在初始化的阶段被读出来了(jin)。当?dng)你可以不厌其烦(ch)地(g)查每一个对象与其他对象的关p,q把那些最昂贵的删除,但是到最后,我们可能?x)因此失M(jin)本想在ORM工具中获得的便利?/p>


一个明昄解决Ҏ(gu)是用Hibernate提供的gq加载机制。这U初始化{略只在一个对象调用它的一对多或多对多关系时才关pd象读取出来。这个过E对开发者来说是透明的,而且只进行了(jin)很少的数据库操作hQ因此会(x)得到比较明显的性能提升。这Ҏ(gu)术的一个缺h延迟加蝲技术要求一个Hibernate?x)话要在对象使用的时候一直开着。这?x)成为通过使用DAO模式持久层抽象出来时的一个主要问题。ؓ(f)?jin)将持久化机制完全地抽象出来Q所有的数据库逻辑Q包括打开或关闭会(x)话,都不能在应用层出现。最常见的是Q一些实C(jin)单接口的DAO实现cd数据库逻辑完全装h?jin)。一U快速但是笨拙的解决Ҏ(gu)是放弃DAO模式Q将数据库连接逻辑加到应用层中来。这可能对一些小的应用程序有效,但是在大的系l中Q这是一个严重的设计~陷Q妨了(jin)pȝ的可扩展性?/p>

在Web层进行gq加?/p>

q运的是QSpring框架为Hibernate延迟加蝲与DAO模式的整合提供了(jin)一U方便的解决Ҏ(gu)。对那些不熟(zhn)Spring与Hibernate集成使用的hQ我不会(x)在这里讨多的l节Q但是我你去?jin)解Hibernate与Spring集成的数据访问。以一个Web应用ZQSpring提供?jin)OpenSessionInViewFilter和OpenSessionInViewInterceptor。我们可以随意选择一个类来实现相同的功能。两U方法唯一的不同就在于interceptor在Spring容器中运行ƈ被配|在web应用的上下文中,而Filter在Spring之前q行q被配置在web.xml中。不用哪个Q他们都在请求将当前?x)话与当前(数据库?j)U程l定时打开Hibernate?x)话。一旦已l定到线E,q个打开?jin)的Hibernate?x)话可以在DAO实现cM透明C用。这个会(x)话会(x)为gq加载数据库中值对象的视图保持打开状态。一旦这个逻辑视图完成?jin),Hibernate?x)话会(x)在Filter的doFilterҎ(gu)或者Interceptor的postHandleҎ(gu)中被关闭。下面是每个lg的配|示例:(x)

 


Interceptor的配|?

 

<beans>
<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor"/>
</list>
</property>
<property name="mappings">

</bean>

<bean name="openSessionInViewInterceptor"
class="org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>
</beans>

Filter的配|?/p>

 

<web-app>

<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate.support.OpenSessionInViewFilter
</filter-class>
</filter>

<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*. spring </url-pattern>
</filter-mapping>

</web-app>


实现Hibernate的Dao接口来用打开的会(x)话是很容易的。事实上Q如果你已经使用?jin)Spring框架来实C的Hibernate Dao,很可能你不需要改变(sh)Q何东ѝ方便的HibernateTemplate公用lg使访问数据库变成菜一,而DAO接口只有通过q个lg才可以访问到数据库。下面是一个示例的DAOQ?/p>


public class HibernateProductDAO extends HibernateDaoSupport implements ProductDAO {

public Product getProduct(Integer productId) {
return (Product)getHibernateTemplate().load(Product.class, productId);
}

public Integer saveProduct(Product product) {
return (Integer) getHibernateTemplate().save(product);
}

public void updateProduct(Product product) {
getHibernateTemplate().update(product);
}
}

 

在业务逻辑层中使用延迟加蝲

即在视囑֤面,Spring框架也通过使用AOP 拦截?HibernateInterceptor来得gq加载变得很Ҏ(gu)实现。这个Hibernate 拦截器透明地将调用配置在Spring应用E序上下文中的业务对象中Ҏ(gu)的请求拦截下来,在调用方法之前打开一个Hibernate?x)话Q然后在Ҏ(gu)执行完之后将?x)话关闭。让我们来看一个简单的例子Q假设我们有一个接口BussinessObjectQ?/p>


public     interface    BusinessObject     {
public     void    doSomethingThatInvolvesDaos();
}
cBusinessObjectImpl实现?jin)BusinessObject接口:

public     class    BusinessObjectImpl    implements    BusinessObject     {
public     void    doSomethingThatInvolvesDaos()     {
//    lots of logic that calls
//    DAO classes Which access
//    data objects lazily  
}  
}  

 


通过在Spring应用E序上下文中的一些配|,我们可以让将调用BusinessObject的方法拦截下来,再o(h)它的Ҏ(gu)支持延迟加蝲。看看下面的一个程序片D:(x)

 


<beans>
<bean id="hibernateInterceptor" class="org.springframework.orm.hibernate.HibernateInterceptor">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="businessObjectTarget" class="com.acompany.BusinessObjectImpl">
<property name="someDAO"><ref bean="someDAO"/></property>
</bean>
<bean id="businessObject" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target"><ref bean="businessObjectTarget"/></property>
<property name="proxyInterfaces">
<value>com.acompany.BusinessObject</value>
</property>
<property name="interceptorNames">
<list>
<value>hibernateInterceptor</value>
</list>
</property>
</bean>
</beans>

当businessObject被调用的时候,HibernateInterceptor打开一个Hibernate?x)话Qƈ调用请求传递给BusinessObjectImpl对象。当BusinessObjectImpl执行完成后,HibernateInterceptor透明地关闭了(jin)?x)话。应用层的代码不用了(jin)解Q何持久层逻辑Q还是实C(jin)延迟加蝲?/p>


在单元测试中试延迟加蝲

最后,我们需要用J-Unit来测试我们的延迟加蝲E序。我们可以轻易地通过重写TestCasecM的setUp和tearDownҎ(gu)来实现这个要求。我比较喜欢用这个方便的抽象cM为我所有测试类的基cR?/p>


public abstract class MyLazyTestCase extends TestCase {

private SessionFactory sessionFactory;
private Session session;

public void setUp() throws Exception {
super.setUp();
SessionFactory sessionFactory = (SessionFactory) getBean("sessionFactory");
session = SessionFactoryUtils.getSession(sessionFactory, true);
Session s = sessionFactory.openSession();
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(s));

}

protected Object getBean(String beanName) {
//Code to get objects from Spring application context
}

public void tearDown() throws Exception {
super.tearDown();
SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
Session s = holder.getSession();
s.flush();
TransactionSynchronizationManager.unbindResource(sessionFactory);
SessionFactoryUtils.closeSessionIfNecessary(s, sessionFactory);
}
}



]]>
վ֩ģ壺 | ղ| | | | ֳ| ʼ| ͼ| ɽ| ƽ| | | | | ³ľ| ¡| | | ӥ̶| »Ȱ| ƶ| ɽ| | ɽ| ɽ| ͭɽ| ϲ| ƽ| ƽ| | | | ƽ| пѷ| Ϫ| ƽ| | | | ÷| |