﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-普通人的奇迹-随笔分类-hibernate</title><link>http://www.blogjava.net/leekiang/category/22103.html</link><description>MDA/MDD/TDD/DDD/DDDDDDD</description><language>zh-cn</language><lastBuildDate>Tue, 15 Apr 2008 13:27:43 GMT</lastBuildDate><pubDate>Tue, 15 Apr 2008 13:27:43 GMT</pubDate><ttl>60</ttl><item><title>Session,SessionFactory,Connetion等</title><link>http://www.blogjava.net/leekiang/archive/2008/03/11/185503.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Tue, 11 Mar 2008 14:43:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2008/03/11/185503.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/185503.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2008/03/11/185503.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/185503.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/185503.html</trackback:ping><description><![CDATA[1,有时连续调多个Dao方法时会报连接关闭，原因往往是关闭session不当。<br />  不要用session.close(),这样会使同一个线程的下一个Dao方法里执行<br />  HibernateSessionFactory.getSession()时取到的是已经被关闭的session,当然会报错了。<br /><br />2，Connection conn =session.connection();<br />  这个conn一定要执行conn.close()吗?<br /><br />3,<br />http://hi.baidu.com/sodarfish/blog/item/b996a3df9224d217622798ec.html<br />在通常的情况下使用DriverManager.getConnection()得到的是一个Connection的实例，当你调用它的close（）方
法时会关闭StateMent和ResultSet。但是我们在使用连接池的过程中，通过连接池得到Connection，当我们调用
Connection的close（）时，Connection并不是被关闭了，而是回到了连接池中，它以后还会被其他的代码取出来使用，如果我们没有关
闭stmt和rs的话，只会使系统中的stmt和rs越来越多。所以在使用连接池后，调用conn.close（）前应先将rs和stmt关闭。<br /><br />
至于为什么调用close()之后不是直接关闭此连接，而是返回给<span class="hilite1">连接池</span>，这是因为dbcp使用委派模型来实现Connection接口了。 <br /><br />http://nymph.blogdriver.com/nymph/180989.html#comment<br />
http://www.javaeye.com/topic/9317?page=1<br />
http://www.javaeye.com/topic/48048?page=1<br />  <br /><img src ="http://www.blogjava.net/leekiang/aggbug/185503.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2008-03-11 22:43 <a href="http://www.blogjava.net/leekiang/archive/2008/03/11/185503.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate记录</title><link>http://www.blogjava.net/leekiang/archive/2008/02/16/180148.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Fri, 15 Feb 2008 21:04:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2008/02/16/180148.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/180148.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2008/02/16/180148.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/180148.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/180148.html</trackback:ping><description><![CDATA[1，hibernate在进行复杂查询的情况下一样可以直接得到一个Map的list: <br />select new Map(a.id as id,a.name as name,b.type as type) from A a,B b where <br />a.id=b.aId; <br />... <br />List mapList=query.list(); <br />.... <br /><br />在jsp页面可以和使用普通的JavaBean一样的方式输出 <br />&lt;c:forEach items="${mapList}" var="m"&gt; <br />&lt;tr&gt; &lt;td&gt; <br />&lt;c:out value="${m.id}"/&gt; &lt;/td&gt; &lt;td&gt; <br />&lt;c:out value="${m.name}"/&gt; &lt;/td&gt; <br />&lt;td&gt; &lt;c:out value="${m.type}"/&gt; &lt;/td&gt; &lt;/tr&gt; <br />&lt;/c:forEach&gt; <br />这样的处理也是很简洁的 <br /><br />2.HQL supports subqueries in the where clause. We can’t think of many good uses
<br />for subqueries in the from clause, although select clause subqueries might be a
<br />nice future extension.<br />不支持from后的子查询，支持where子查询<br />http://blog.zol.com.cn/655/article_654256.html<br /><br />3， String sql="select {fi.*} from FuncInfo fi " +<br />   "left join RoleSubFunc rsf on fi.FuncId=rsf.FuncId "+ <br />       "left join RoleInfo ri on rsf.RoleId=ri.RoleId "+ <br />       "left join UserRole ur on ri.RoleId=ur.RoleId "+ <br />       "where ur.UserId='"+userId+"'";//可以无限向上找父级<br /> List list =session.createSQLQuery(sql).addEntity("fi", FuncInfo.class).list();<br /><br />4,<font face="Times New Roman">为什么Hibernate 3中的HQL无法查询汉字<br />使用同样的代码和配置文件，在Hibernate 2上完全没有问题，在Hibernate 3中，使用如下HQL查询，无法得到正确的结果集：<br />String hql = "from story where title like '%汉字%'"; <br />Query q = session.createQuery(hql); <br />但用下面的HQL查询，却可以得到正确结果集：<br />String hql = " from story where title like '%english%'"; <br />Query q = session.createQuery(hql); <br />答：如果采用的是拼接HQL的方式，从Hibernate 2升级到Hibernate 3确实会出现汉字乱码问题。在控制台中可以看到，SQL的汉字部分变成了乱码：<br />[DEBUG]
2005-08-14 14:33:58 org.hibernate.SQL - "select story0_.content from
story as story0_ where story0_.title like
'%&amp;–°é—&amp;&amp;Š¨&amp;€' <br />在Hibernate中，查询时应尽量使用占位符的写法（如下），这样既可以避免乱码问题，又可以避免潜在的SQL注入攻击：<br />getHibernate().find("from story where title like ? ", "%汉字%")</font><img src ="http://www.blogjava.net/leekiang/aggbug/180148.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2008-02-16 05:04 <a href="http://www.blogjava.net/leekiang/archive/2008/02/16/180148.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>升级到hibernate3.2</title><link>http://www.blogjava.net/leekiang/archive/2007/10/09/151197.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Mon, 08 Oct 2007 18:03:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2007/10/09/151197.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/151197.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2007/10/09/151197.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/151197.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/151197.html</trackback:ping><description><![CDATA[
		<p>1,从Hibernate 3.0.x/3.1.x升级到最新的3.2版，一定要注意，3.2版的很多sql函数如count(), sum()的唯一返回值已经从Integer变为Long，如果不升级代码，会得到一个ClassCastException。</p>
		<p>这个变化主要是为了兼容JPA，可以在hibernate.org的最新文档中找到说明。</p>
		<p>Hibernate Team也提供了一个与原来兼容的解决方案：</p>
		<p>  Configuration classicCfg = new Configuration(); <br />  classicCfg.addSqlFunction( "count", new ClassicCountFunction()); <br />  classicCfg.addSqlFunction( "avg", new ClassicAvgFunction()); <br />  classicCfg.addSqlFunction( "sum", new ClassicSumFunction()); <br />  SessionFactory classicSf = classicCfg.buildSessionFactory(); <br /><br />或</p>
		<p>int count = ((Integer)q.uniqueResult()).intValue();</p>
		<p>改成 int count = ((Number)q.uniqueResult()).intValue(); 这样就可以两个版本同时兼容.<br /><br />2,hibernate3.2要求ehcache1.2</p>
		<p>3,session.createSQLQuery(sql).executeUpdate();这个hibernate3.0.5不支持,而hibernate3.2支持</p>
		<p>  session.createSQLQuery(fsql).addScalar("singlevalue",<br />                        Hibernate.DOUBLE).uniqueResult();这个到了3.2就不需要addScalar了.</p>
		<p>4,session.createSQLQuery(sql).addEntity(Class class);hibernate3.0.5不支持，单个参数的addEntity方法</p>
		<p>5，hibernate3.2可以对原生sql 查询使用ResultTransformer。这会返回不受Hibernate管理的实体。<br />sess.createSQLQuery("SELECT NAME, BIRTHDATE FROM CATS")<br />        .setResultTransformer(Transformers.aliasToBean(CatDTO.class))<br />上面的查询将会返回CatDTO的列表,它将被实例化并且将NAME和BIRTHDAY的值注射入对应的属性或者字段。 <br /></p>
		<p>
				<br /> </p>
<img src ="http://www.blogjava.net/leekiang/aggbug/151197.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2007-10-09 02:03 <a href="http://www.blogjava.net/leekiang/archive/2007/10/09/151197.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate问题</title><link>http://www.blogjava.net/leekiang/archive/2007/09/28/148919.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Thu, 27 Sep 2007 19:51:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2007/09/28/148919.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/148919.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2007/09/28/148919.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/148919.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/148919.html</trackback:ping><description><![CDATA[1,get一个对象并打算修改这个对象时，hibernate会判断该对象的属性值是否有变动，如果没有任何变动，hibernate不会执行update语句。在同时修改页面上的多条记录时可发现这一点。<br /><br />2,执行以下语句时hibernate3.0.5会报错,而3.2不会<br />sql="select 1+1 from dual";<br />session.createSQLQuery(sql).uniqueResult()<br />报错:addScalar() or addEntity() must be called on a sql query before executing the query.<br /><br />3,&lt;many-to-one&gt; 的lazy设置为true时，get子对象不会把该父对象抓过来,但可以手动写代码抓取父对象<br />如 Son son =(Son)this.getHibernateTemplate().get(Son.class, id);<br />       然后执行 son.getParent().getName();<br />   这样不仅仅会抓取到name,其他所有的属性如age,sex等都会取到，即用p.getParent().getAge()达到了同样的效果，后台都执行了select * from parent where id=?   注意用p.getParent()仅能得到parent的id.<br />   这时debug查看parent对象的内存快照,看到的是一个用cglib实现的代理对象,<br />Hibernate通过使用CGLIB,来实现动态构造一个目标对象的代理类对象，并且在代理类对象中包含目标对象的所有属性和方法，而且所有属性均被赋值为null。通过调试器显示的内存快照，我们可以看出此时真正的User对象，是包含在代理对象的CGLIB$CALBACK_0.target属性中，当调用son.getName()方法，这时通过CGLIB赋予的回调机制，实际上调用CGLIB$CALBACK_0.getName()方法，当调用该方法时，Hibernate会首先检查CGLIB$CALBACK_0.target属性是否为null，如果不为空，则调用目标对象的getName方法，如果为空，则会发起数据库查询，生成类似这样的SQL语句：select * from parent where id=’1’;来查询数据，并构造目标对象，并且将它赋值到CGLIB$CALBACK_0.target属性中。<br />这样，通过一个中间代理对象，Hibernate实现了实体的延迟加载，只有当用户真正发起获得实体对象属性的动作时，才真正会发起数据库查询操作。<br />    <span style="COLOR: #0010ff">&lt;many-to-one&gt; 的lazy设置为false时,抓取父对象没有采用代理机制。<br /></span><span style="BACKGROUND-COLOR: #ffffff"></span><br />4,用session.close()，执行多次查询后报session is closed的错误,而hibernateSessionFactory.closeSession()没有这个问题，这是什么原因?<br /><br />   <br /><img src ="http://www.blogjava.net/leekiang/aggbug/148919.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2007-09-28 03:51 <a href="http://www.blogjava.net/leekiang/archive/2007/09/28/148919.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate批量处理(转)</title><link>http://www.blogjava.net/leekiang/archive/2007/09/27/148688.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Thu, 27 Sep 2007 06:22:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2007/09/27/148688.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/148688.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2007/09/27/148688.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/148688.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/148688.html</trackback:ping><description><![CDATA[在做大批量处理时，容易出现outofmemory的情况，分析及解决如下 <br />（1）原因 <br /> 当首次作Insertupdatedeleteselect时，新产生的object在session关闭之前将自动装载到session级别的缓存区，如果，AP使用了二级缓存，同样也会装入到二级缓存。所以当数据量大时，就会出现outofmemory情况。 <br />  <br />（2）解决方法 <br />  <br />(A)批量插入（Batch inserts）/批量更新（Batch updates） <br />必须通过经常的调用 <tt class="literal"><font face="新宋体">flush()</font></tt> 以及稍后调用 <tt class="literal"><font face="新宋体">clear()</font></tt> 来控制第一级缓存的大小 <br />如： <br />Session session = sessionFactory.openSession();<br />Transaction tx = session.beginTransaction();<br />   <br />for ( int i=0; i&lt;100000; i++ ) {<br />    Customer customer = new Customer(.....);<br />    session.save(customer);<br />    if ( i % 20 == 0 ) { <br />//20, same as the JDBC batch size //20,与JDBC批量设置相同<br />        //flush a batch of inserts and release memory:<br />        //将本批插入的对象立即写入数据库并释放内存<br />        session.flush();<br />        session.clear();<br />    }<br />}<br />   <br />tx.commit();<br />session.close(); <br />  <br />(B)大批量更新/删除（Bulk update/delete） <br />使用HQL语言 <br />  <pre class="programlisting">Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();

        String hqlUpdate = "update Customer set name = :newName where name = :oldName";
        int updatedEntities = s.createQuery( hqlUpdate )
                            .setString( "newName", newName )
                            .setString( "oldName", oldName )
                            .executeUpdate();
        tx.commit();
        session.close();</pre><br />执行一个HQL <tt class="literal"><font face="新宋体">DELETE</font></tt>，同样使用 <tt class="literal"><font face="新宋体">Query.executeUpdate()</font></tt> 方法 （此方法是为 那些熟悉JDBC <tt class="literal"><font face="新宋体">PreparedStatement.executeUpdate()</font></tt> 的人们而设定的） <pre class="programlisting">Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();

        String hqlDelete = "delete Customer where name = :oldName";
        int deletedEntities = s.createQuery( hqlDelete )
                            .setString( "oldName", oldName )
                            .executeUpdate();
        tx.commit();
        session.close();</pre><img src ="http://www.blogjava.net/leekiang/aggbug/148688.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2007-09-27 14:22 <a href="http://www.blogjava.net/leekiang/archive/2007/09/27/148688.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mant-to-one not-found</title><link>http://www.blogjava.net/leekiang/archive/2007/06/08/122947.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Fri, 08 Jun 2007 14:48:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2007/06/08/122947.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/122947.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2007/06/08/122947.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/122947.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/122947.html</trackback:ping><description><![CDATA[<span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">mant-to-one元素有一个属性:not-found。<br>用来指定引用的外键不存在时将如何处理：<br>exception（默认）抛出异常<br>ignore 忽略<br>Hibernate就采用默认的抛出异常来处理</span>
<img src ="http://www.blogjava.net/leekiang/aggbug/122947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2007-06-08 22:48 <a href="http://www.blogjava.net/leekiang/archive/2007/06/08/122947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>摘录</title><link>http://www.blogjava.net/leekiang/archive/2007/04/29/114590.html</link><dc:creator>leekiang</dc:creator><author>leekiang</author><pubDate>Sun, 29 Apr 2007 07:55:00 GMT</pubDate><guid>http://www.blogjava.net/leekiang/archive/2007/04/29/114590.html</guid><wfw:comment>http://www.blogjava.net/leekiang/comments/114590.html</wfw:comment><comments>http://www.blogjava.net/leekiang/archive/2007/04/29/114590.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/leekiang/comments/commentRss/114590.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/leekiang/services/trackbacks/114590.html</trackback:ping><description><![CDATA[<p>摘录自&nbsp;<a href="http://www.javaeye.com/topic/73047?page=7">http://www.javaeye.com/topic/73047?page=7</a><br>&nbsp;&nbsp;&nbsp; 在实际使用Hibernate的例子中，我比较倾向于使用单个的PO，PO的逻辑关系由程序保证。当然这种设计不符合 Hibernate的思想，不过我的目的是解决问题，根据实际经验来看，这样做在项目中更有实际价值。我用Hibernate的目的只是不想写那么多Jdbc操作，我不打算用他来封装我的业务关系。我的业务逻辑体现是在数据库设计上体现。而程序开发的时候，表的关系是遵循模型设计开发，模型设计中会强制要求开发人员必须遵守模型的关系规则。虽然这样，会在代码中有很多不雅的代码（比起在PO表达对象关系来说），但是我觉得更可控。</p>
<img src ="http://www.blogjava.net/leekiang/aggbug/114590.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/leekiang/" target="_blank">leekiang</a> 2007-04-29 15:55 <a href="http://www.blogjava.net/leekiang/archive/2007/04/29/114590.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>