mypure
2009-04-27 16:28
浏览 209
已采纳

Hibernat泛型DAO问题

在程序中使用springside的DAO,使用级联时候出现问题

[code="java"]

public class SimpleHibernateDao {

protected Logger logger = LoggerFactory.getLogger(getClass());

protected SessionFactory sessionFactory;

protected Class<T> entityClass;

/**
 * 用于扩展的DAO子类使用的构造函数.
 * 
 * 通过子类的泛型定义取得对象类型Class.
 * eg.
 * public class UserDao extends SimpleHibernateDao<User, Long>
 */
public SimpleHibernateDao() {
    this.entityClass = ReflectionUtils.getSuperClassGenricType(getClass());
}

/**
 * 用于Service层直接使用SimpleHibernateDAO的构造函数.
 * eg.
 * SimpleHibernateDao<User, Long> userDao = new SimpleHibernateDao<User, Long>(sessionFactory, User.class);
 */
public SimpleHibernateDao(final SessionFactory sessionFactory, final Class<T> entityClass) {
    this.sessionFactory = sessionFactory;
    this.entityClass = entityClass;
}

public SessionFactory getSessionFactory() {
    return sessionFactory;
}

///................其他省略

}

[code="java"]
public class HibernateDao extends SimpleHibernateDao {
/**
* 用于扩展的DAO子类使用的构造函数.
*
* 通过子类的泛型定义取得对象类型Class.
* eg.
* public class UserDao extends HibernateDao{
* }
*/
public HibernateDao() {
super();
}

/**
 * 用于Service层直接使用HibernateDAO的构造函数.
 * eg.
 * HibernateDao<User, Long> userDao = new HibernateDao<User, Long>(sessionFactory, User.class);
 */
public HibernateDao(final SessionFactory sessionFactory, final Class<T> entityClass) {
    super(sessionFactory, entityClass);
}

// 分页查询函数 //

/**
 * 分页获取全部对象. 
 */
public Page<T> getAll(final Page<T> page) {
    return findByCriteria(page);
}

//其他
}

下面是实体
[/code]

[code="java"]

@Entity
@Table(name = "WFPROCESSINST", schema = "TSSA")
@Proxy(lazy=false)
public class Wfprocessinst implements java.io.Serializable {
private BigDecimal processinstid;
@Id
@Column(name = "PROCESSINSTID", unique = true, nullable = false, precision = 22, scale = 0)
public BigDecimal getProcessinstid() {
return this.processinstid;
}

public void setProcessinstid(BigDecimal processinstid) {
    this.processinstid = processinstid;
}
private String processinstname;
private Set<Wftransition> wftransitions = new HashSet<Wftransition>(0);
     @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "wfprocessinst")
public Set<Wfactivityinst> getWfactivityinsts() {
    return this.wfactivityinsts;
}

public void setWfactivityinsts(Set<Wfactivityinst> wfactivityinsts) {
    this.wfactivityinsts = wfactivityinsts;
}

}
[/code]

当fetch = FetchType.EAGER 报错,为FetchType.LAZY 正常。

异常

[WARN ]2009-04-27 16:26:57,868 org.hibernate.util.JDBCExceptionReporter SQL Error: 17027, SQLState: null
[ERROR]2009-04-27 16:26:57,868 org.hibernate.util.JDBCExceptionReporter 流已被关闭
[INFO ]2009-04-27 16:26:57,870 org.hibernate.event.def.DefaultLoadEventListener Error performing load command
org.hibernate.exception.GenericJDBCException: could not load an entity: [cn.com.starit.orm.hibernate.dojo.Wfprocessinst#8809358]
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1874)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3044)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:395)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:375)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:139)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:179)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:103)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
at org.hibernate.impl.SessionImpl.load(SessionImpl.java:795)
at org.hibernate.impl.SessionImpl.load(SessionImpl.java:788)
at cn.com.starit.orm.hibernate.SimpleHibernateDao.get(SimpleHibernateDao.java:114)
at cn.com.starit.orm.hibernate.EntityManager.get(EntityManager.java:38)
at cn.com.starit.orm.hibernate.EntityManager$$FastClassByCGLIB$$7a912d89.invoke()
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
at cn.com.starit.service.WFManager$$EnhancerByCGLIB$$e9c4798f.get()
at cn.com.starit.action.UserAction.main(UserAction.java:21)
Caused by: java.sql.SQLException: 流已被关闭
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
at oracle.jdbc.driver.LongAccessor.getBytes(LongAccessor.java:151)
at oracle.jdbc.driver.LongAccessor.getString(LongAccessor.java:193)
at oracle.jdbc.driver.T4CLongAccessor.getString(T4CLongAccessor.java:422)
at oracle.jdbc.driver.OracleResultSetImpl.getString(OracleResultSetImpl.java:397)
at oracle.jdbc.driver.OracleResultSet.getString(OracleResultSet.java:1515)
at org.hibernate.type.StringType.get(StringType.java:18)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:163)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:154)
at org.hibernate.type.AbstractType.hydrate(AbstractType.java:81)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2096)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1380)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1308)
at org.hibernate.loader.Loader.getRow(Loader.java:1206)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:580)
at org.hibernate.loader.Loader.doQuery(Loader.java:701)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1860)
[b]问题补充:[/b]
代码被我没有有发完,是有的。
[b]问题补充:[/b]
级联查询
ApplicationContext context = new ClassPathXmlApplicationContext(
"classpath:config/ApplicationContext.xml");
WFManager wf = (WFManager) context.getBean("WFManager");
Wfprocessinst dd;
try {
dd= wf.get(new BigDecimal(8809358));
System.out.println(dd.getProcessinstname());
//Iterator ac= dd.getWfactivityinsts().iterator();
// while(ac.hasNext()){
// System.out.println(ac.next().getActivityinstname());
//

// }
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("this is a test");
注释那一部分有问题
[b]问题补充:[/b]
我做了一个简单例子,还是错的,控制台输出的SQL是正确的
[b]问题补充:[/b]
是的哦,搞半天来了,没有搞定。

输出的SQL是正常的。
不是为什么哦?
[b]问题补充:[/b]
我用list试试
[b]问题补充:[/b]
怎么个用法,发端代码看看。
[b]问题补充:[/b]
还是不知道怎么解决哦?
[b]问题补充:[/b]
我先试试,问题先不关闭

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

5条回答 默认 最新

  • wanghaolovezlq 2009-04-27 21:25
    已采纳

    细看了下你的代码,
    是这部分导致!
    entity = (T) getSession().load(getPersistentClass(), id,
    [color=red]LockMode.UPGRADE[/color]);

    任何关联的对象或者包含的集合都不会被以LockMode.UPGRADE方式返回,除非你指定了lock或all作为关联的级联风格(cascade="all"或cascade="lock")!

    如果类的映射使用了代理,load方式返回的是一个未初始化的代理,直接你调用该代理的方法才会去访问数据库,所以,自然相关的级联集合也只有到比如dd.getWfactivityinsts()的时候才去数据库里查找,

    基本上,你改成load改成get应该就没问题了

    已采纳该答案
    打赏 评论
  • wanghaolovezlq 2009-04-27 17:51

    Wfprocessinst 这个类代码不全吧,

    private Set wftransitions = new HashSet(0);

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "wfprocessinst")

    public Set getWfactivityinsts() {

    return [color=red]this.wfactivityinsts; [/color]//这个成员变量都没有

    }

    public void setWfactivityinsts(Set wfactivityinsts) {

    this.wfactivityinsts = wfactivityinsts;

    }

    打赏 评论
  • wanghaolovezlq 2009-04-27 19:59

    你是进行级联更新还是级联查询,或。。。导致的,出错的代码部分是。。

    打赏 评论
  • wanghaolovezlq 2009-04-27 20:17

    大概知道你的问题了,
    用了这个方法iterator()来取数据,是有些问题,它在session关闭后,就得不到数据了
    要用list()就没问题了

    打赏 评论
  • wanghaolovezlq 2009-04-27 20:22

    Hibernate Iterator的查询本身是分为两步的:

    ==> select id from cat
    ==> select * from cat where id = ?
    ==> select * from cat where id = ?
    ...
    ==> select * from cat where id = ?

    第一步,去数据库中取主键列表,
    [color=red]第二步,按照主键一个一个取数据//你的就是在这步就出现那个问题了[/color]

    打赏 评论

相关推荐 更多相似问题