Spring+Hibernate困扰了我几天的问题

xhf1234 2008-08-06 06:43:00
数据库有2张表
family (id,name)
member (id,name)

其中member通过外键familyID形成一对多关系

我的测试类如下:
************************************
package test;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import springDAO.*;
public class Test{

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
FamilyDAO fDAO = (FamilyDAO)ctx.getBean("FamilyDAOProxy");
MemberDAO mDAO = (MemberDAO)ctx.getBean("MemberDAOProxy");

Family f = fDAO.findById(1);
Member m = new Member();
m.setName("t");
f.getMembers().add(m);
fDAO.attachDirty(f);
}


}

意图是从family表中读取ID=1的family,然后加入一个属性member,然后更新
但是程序报错了,调试发现在 f.getMembers().add(m); 处报异常
出错信息:
f.getMembers().add(m);
f.getMembers().add(m);
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: springDAO.Family.members, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
at org.hibernate.collection.AbstractPersistentCollection.write(AbstractPersistentCollection.java:183)
at org.hibernate.collection.PersistentSet.add(PersistentSet.java:165)
at test.Test.main(Test.java:22)

我试过以下代码段运行正确:
Family f = new Family();
f.setName("t");
Member m = new Member();
m.setName("t");
f.getMembers().add(m);
fDAO.save(f);
也就是只能新建不能更新??????????


大虾们帮帮忙啊,已经因为这问题郁闷了几天了。。。。。。。。
我愿意散尽我所有的分求得答案!!!
谢谢,谢谢 55




用的是MyEclipse,自动生成了很多文件
下边是我的配置文件以及POJO

**********************************************************************************
hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>

<session-factory>
<property name="connection.username">root</property>
<property name="connection.url">
jdbc:mysql://localhost:3306
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="myeclipse.connection.profile">
localhost
</property>
<property name="connection.password">lifebegin</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<mapping resource="springDAO/Family.hbm.xml" />
<mapping resource="springDAO/Member.hbm.xml" />

</session-factory>

</hibernate-configuration>
*****************************************************************************************


映射文件Member.hbm.xml
******************************************************************************************
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="springDAO.Member" table="member" catalog="ttt">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<many-to-one name="family" class="springDAO.Family" update="false" insert="false" fetch="select">
<column name="id" not-null="true" unique="true" />
</many-to-one>
<property name="name" type="java.lang.String">
<column name="name" length="45" not-null="true" />
</property>
</class>
</hibernate-mapping>

映射文件Family.hbm.xml
*************************************************************************************

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="springDAO.Family" table="family" catalog="ttt">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="45" not-null="true" />
</property>
<set name="members" inverse="true" cascade="all">
<key>
<column name="id" not-null="true" unique="true" />
</key>
<one-to-many class="springDAO.Member" />
</set>
</class>
</hibernate-mapping>

下页续
...全文
174 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
shuai45 2008-08-07
  • 打赏
  • 举报
回复
楼主辛苦了,到底想干啥
atealxt 2008-08-07
  • 打赏
  • 举报
回复
可能是延迟加载的问题,看看相关技术。

先在hbm.xml里给members设置lazy="false"试试。
qlrhoo 2008-08-07
  • 打赏
  • 举报
回复
楼主你太辛苦了
这问题还是自己去看看
按部就班从新弄一次,这也没多少东西
就是辛苦努了
brz97 2008-08-07
  • 打赏
  • 举报
回复
1.lazy=false不过对于1对多的关系不起作用
2.自己重新生成session启动一个查询过程
mike1980 2008-08-07
  • 打赏
  • 举报
回复
[Quote=引用楼主 xhf1234 的帖子:]
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: springDAO.Family.members, no session or session was closed
[/Quote]

根据虚拟机报的异常为:延迟加载初始化异常。
由于你的两张表的映射对象设置了关联,由于Hibernate的延迟加载机制,对于这种具有关联关系的对象容易出现该异常。
即当处于延迟加载时,你第一次读取关联的对象时,Hibernate只缓存了该关联对象的主键,而其他属性并未加载;
这时Hibernate会去读数据库,通常这时session已经被关闭,因此产生这个异常。
对于你说的:“能写不能读。”是由于写的时候并未写入数据库,而是写入的缓存,所以他并不影响写入。
建议你将family对象中的集合members的延迟加载的策略为false。

<set name="members" inverse="true" cascade="all" lazy="false">

gvc068932 2008-08-07
  • 打赏
  • 举报
回复
我来解决吧。

懒加载打开(默认就是打开)。

web.xml加这个

<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>

</init-param>

</filter>

applicationContext.xml加这个

AOP事务管理
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>

<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" timeout="60" read-only="false" rollback-for="java.lang.Exception"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="remove*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>

<aop:config>
<aop:pointcut id="txAdviceCommon" expression="execution(* 包名.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="txAdviceCommon" />
</aop:config>

具体配置自己去研究学习。
Landor2004 2008-08-07
  • 打赏
  • 举报
回复
springDAO.Family.members, no session or session was closed
session已经关闭之后,要对session进行了操作,主要都是在延迟加载的问题上,有以下几个解决方案

1 <set name="members" inverse="true" cascade="all" lazy="false"> 取消延迟加载
这个不可取,如果我只查主表的话,还要查出字表信息,影响了性能

2 在查询的时候,用关联fetch来关联抓取,
例如createQuery("select a from A a left join fetch a.xxxs"),这是推荐的做法
wwwtyb 2008-08-07
  • 打赏
  • 举报
回复
failed to lazily initialize a collection of role

在Family.hbm.xml 中的 <set name="members" inverse="true" cascade="all" lazy="false"> 中加一个lazy="false"属性.
dryZeng 2008-08-07
  • 打赏
  • 举报
回复
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: springDAO.Family.members, no session or session was closed

在Family.hbm.xml 中的<set name="members" inverse="true" cascade="all" lazy="false"> 中加一个lazy="false"属性.
xhf1234 2008-08-06
  • 打赏
  • 举报
回复

MemberDAO.java
******************************************************
package springDAO;

import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.LockMode;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
* A data access object (DAO) providing persistence and search support for
* Member entities. Transaction control of the save(), update() and delete()
* operations can directly support Spring container-managed transactions or they
* can be augmented to handle user-managed Spring transactions. Each of these
* methods provides additional information for how to configure it for the
* desired type of transaction control.
*
* @see springDAO.Member
* @author MyEclipse Persistence Tools
*/

public class MemberDAO extends HibernateDaoSupport {
private static final Log log = LogFactory.getLog(MemberDAO.class);
// property constants
public static final String NAME = "name";

protected void initDao() {
// do nothing
}

public void save(Member transientInstance) {
log.debug("saving Member instance");
try {
getHibernateTemplate().save(transientInstance);
log.debug("save successful");
} catch (RuntimeException re) {
log.error("save failed", re);
throw re;
}
}

public void delete(Member persistentInstance) {
log.debug("deleting Member instance");
try {
getHibernateTemplate().delete(persistentInstance);
log.debug("delete successful");
} catch (RuntimeException re) {
log.error("delete failed", re);
throw re;
}
}

public Member findById(java.lang.Integer id) {
log.debug("getting Member instance with id: " + id);
try {
Member instance = (Member) getHibernateTemplate().get(
"springDAO.Member", id);
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}

public List findByExample(Member instance) {
log.debug("finding Member instance by example");
try {
List results = getHibernateTemplate().findByExample(instance);
log.debug("find by example successful, result size: "
+ results.size());
return results;
} catch (RuntimeException re) {
log.error("find by example failed", re);
throw re;
}
}

public List findByProperty(String propertyName, Object value) {
log.debug("finding Member instance with property: " + propertyName
+ ", value: " + value);
try {
String queryString = "from Member as model where model."
+ propertyName + "= ?";
return getHibernateTemplate().find(queryString, value);
} catch (RuntimeException re) {
log.error("find by property name failed", re);
throw re;
}
}

public List findByName(Object name) {
return findByProperty(NAME, name);
}

public List findAll() {
log.debug("finding all Member instances");
try {
String queryString = "from Member";
return getHibernateTemplate().find(queryString);
} catch (RuntimeException re) {
log.error("find all failed", re);
throw re;
}
}

public Member merge(Member detachedInstance) {
log.debug("merging Member instance");
try {
Member result = (Member) getHibernateTemplate().merge(
detachedInstance);
log.debug("merge successful");
return result;
} catch (RuntimeException re) {
log.error("merge failed", re);
throw re;
}
}

public void attachDirty(Member instance) {
log.debug("attaching dirty Member instance");
try {
getHibernateTemplate().saveOrUpdate(instance);
log.debug("attach successful");
} catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
}

public void attachClean(Member instance) {
log.debug("attaching clean Member instance");
try {
getHibernateTemplate().lock(instance, LockMode.NONE);
log.debug("attach successful");
} catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
}

public static MemberDAO getFromApplicationContext(ApplicationContext ctx) {
return (MemberDAO) ctx.getBean("MemberDAO");
}
}

spring配置文件applicationContest.xml
*************************************************************************
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">




<bean id="SessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation"
value="file:src/hibernate.cfg.xml">
</property>
</bean>
<bean id="FamilyDAO" class="springDAO.FamilyDAO">
<property name="sessionFactory">
<ref bean="SessionFactory" />
</property>
</bean>
<bean id="MemberDAO" class="springDAO.MemberDAO">
<property name="sessionFactory">
<ref bean="SessionFactory" />
</property>
</bean>


<!-- DAO代理 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="SessionFactory" />
</property>
</bean>

<bean id="FamilyDAOProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="proxyTargetClass">
<value>true</value>
</property>
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="FamilyDAO" />
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<bean id="MemberDAOProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="proxyTargetClass">
<value>true</value>
</property>
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="MemberDAO" />
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

</beans>
xhf1234 2008-08-06
  • 打赏
  • 举报
回复

POJO:
*Family.java
*****************************************************************
package springDAO;

import java.util.HashSet;
import java.util.Set;

/**
* Family entity.
*
* @author MyEclipse Persistence Tools
*/

public class Family implements java.io.Serializable {

// Fields

private Integer id;
private String name;
private Set members = new HashSet(0);

// Constructors

/** default constructor */
public Family() {
}

/** minimal constructor */
public Family(Integer id, String name) {
this.id = id;
this.name = name;
}

/** full constructor */
public Family(Integer id, String name, Set members) {
this.id = id;
this.name = name;
this.members = members;
}

// Property accessors

public Integer getId() {
return this.id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public Set getMembers() {
return this.members;
}

public void setMembers(Set members) {
this.members = members;
}

}

FamilyDAO.java
************************************************************************
package springDAO;

import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.LockMode;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
* A data access object (DAO) providing persistence and search support for
* Family entities. Transaction control of the save(), update() and delete()
* operations can directly support Spring container-managed transactions or they
* can be augmented to handle user-managed Spring transactions. Each of these
* methods provides additional information for how to configure it for the
* desired type of transaction control.
*
* @see springDAO.Family
* @author MyEclipse Persistence Tools
*/

public class FamilyDAO extends HibernateDaoSupport {
private static final Log log = LogFactory.getLog(FamilyDAO.class);
// property constants
public static final String NAME = "name";

protected void initDao() {
// do nothing
}

public void save(Family transientInstance) {
log.debug("saving Family instance");
try {
getHibernateTemplate().save(transientInstance);
log.debug("save successful");
} catch (RuntimeException re) {
log.error("save failed", re);
throw re;
}
}

public void delete(Family persistentInstance) {
log.debug("deleting Family instance");
try {
getHibernateTemplate().delete(persistentInstance);
log.debug("delete successful");
} catch (RuntimeException re) {
log.error("delete failed", re);
throw re;
}
}

public Family findById(java.lang.Integer id) {
log.debug("getting Family instance with id: " + id);
try {
Family instance = (Family) getHibernateTemplate().get(
"springDAO.Family", id);
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}

public List findByExample(Family instance) {
log.debug("finding Family instance by example");
try {
List results = getHibernateTemplate().findByExample(instance);
log.debug("find by example successful, result size: "
+ results.size());
return results;
} catch (RuntimeException re) {
log.error("find by example failed", re);
throw re;
}
}

public List findByProperty(String propertyName, Object value) {
log.debug("finding Family instance with property: " + propertyName
+ ", value: " + value);
try {
String queryString = "from Family as model where model."
+ propertyName + "= ?";
return getHibernateTemplate().find(queryString, value);
} catch (RuntimeException re) {
log.error("find by property name failed", re);
throw re;
}
}

public List findByName(Object name) {
return findByProperty(NAME, name);
}

public List findAll() {
log.debug("finding all Family instances");
try {
String queryString = "from Family";
return getHibernateTemplate().find(queryString);
} catch (RuntimeException re) {
log.error("find all failed", re);
throw re;
}
}

public Family merge(Family detachedInstance) {
log.debug("merging Family instance");
try {
Family result = (Family) getHibernateTemplate().merge(
detachedInstance);
log.debug("merge successful");
return result;
} catch (RuntimeException re) {
log.error("merge failed", re);
throw re;
}
}

public void attachDirty(Family instance) {
log.debug("attaching dirty Family instance");
try {
getHibernateTemplate().saveOrUpdate(instance);
log.debug("attach successful");
} catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
}

public void attachClean(Family instance) {
log.debug("attaching clean Family instance");
try {
getHibernateTemplate().lock(instance, LockMode.NONE);
log.debug("attach successful");
} catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
}

public static FamilyDAO getFromApplicationContext(ApplicationContext ctx) {
return (FamilyDAO) ctx.getBean("FamilyDAO");
}
}



Member.java
************************************************************
package springDAO;

/**
* Member entity.
*
* @author MyEclipse Persistence Tools
*/

public class Member implements java.io.Serializable {

// Fields

private Integer id;
private Family family;
private String name;

// Constructors

/** default constructor */
public Member() {
}

/** full constructor */
public Member(Integer id, Family family, String name) {
this.id = id;
this.family = family;
this.name = name;
}

// Property accessors

public Integer getId() {
return this.id;
}

public void setId(Integer id) {
this.id = id;
}

public Family getFamily() {
return this.family;
}

public void setFamily(Family family) {
this.family = family;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

}

下页续

81,090

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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