hibernate筆記

 org.hibernate.MappingException: entity class not found
出現這個問題可能有兩個緣由
 
一、多是hbm.xml文件沒有與對象類對應
二、多是hbm.xml配置文件裏的類地址指示錯誤
 
直接繼承hibernatedaosupport可能會出現 no session的問題
解決辦法:
一、直接在applicationcontext.xml文件裏配置並在類裏注入
二、直接在須要繼承的類中寫入一下代碼:
   @Autowired
    public void setSessionFactoryOverride(SessionFactory sessionFactory)
    {
        super.setSessionFactory(sessionFactory);
    }
三、在ac 裏注入session並由每一個實體繼承
 
node to traverse cannot be null!
<property name="mappingDirectoryLocations">   
            <list>   
                <value>   
                    classpath*:/com/zhueli/soft/hr/entity/*.hbm.xml   
                </value>   
            </list>   
        </property> 
你這個地方寫的不對吧,mappingDirectoryLocations屬性說的就是目錄位置,你爲何還要*.hbm.xml   呢,指定到目錄就能夠了classpath*:/com/zhueli/soft/hr/entity/
 
把property的name屬性值改成mappingResources。即 
<property name="mappingResources">  
            <list>  
                <value>  
                    classpath*:/com/zhueli/soft/hr/entity/*.hbm.xml  
                </value>  
            </list>  
        </property>    
 <generator class="native" />
注意這個爲native纔會自動插入主鍵

 

 主動測試時候不須要加「
save返回的是主鍵的值+1
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
最後記得要加上這個setter,用於轉換結果爲map
利用上面這個方式,能夠用hibernate執行普通語句,也能夠用對象來執行來操做,可是,用對象必須得配置映射文件!必須配置配置,沒得商量,配置好後直接用掃描文件的方式統一加入hibernate配置文件,另外,用普通sql查出的數據,只能用map鍵值對方式來取值,而不能直接泛型爲。
 
試試動態映射表名:
 
hbm與註解共存,須要配置爲註解的class ,而後掃包方式照樣
 
讀取實體類映射的三種方法
mappingResources,annotatedClasses,packagesToScan(讀取實體類映射)
 
 
 
另外一種能夠純sql的方法(半純):
static List sql() {
  Session s = HibernateUtil.getSession();
  Query q = s.createSQLQuery("select * from user").addEntity(User.class);
  List<User> rs = q.list();
  s.close();
  return rs;
 }
 
hibernate的命名查詢相似於mybatis
static List namedQuery(int id) {
  Session s = HibernateUtil.getSession();
  Query q = s.getNamedQuery("getUserById");
  q.setInteger("id", id);
  return q.list();
 }
<?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">
<hibernate-mapping>
    <class name="com.sy.vo.User" table="user" catalog="news">
    </class>
    <!-- 命名查詢:定義查詢條件 -->
    <query name="getUserById">
     <![CDATA[from User where id=:id]]>
    </query>
    <!-- 命名查詢中使用sql,不推薦使用,影響跨數據庫
    <sql-query name="getUserById2">
     <![CDATA[select * from User where ]]>
    </sql-query> -->
</hibernate-mapping>
 
   <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
    <property name="sessionFactory" ref="sessionFactory" />
    </bean>經過在配置文件裏面寫上這個,再在dao的實現類裏面用@autowired來聲明便可直接使用getHibernateTemplate對象來操做HQL語句!而表面上就脫離了hibernatedaosupport,不用再去繼承了。
 
.createSQLQuery("insert into test(name) values ('測試事務333')");
記得是createSQLQuery才能執行insert,不然會values no tokens
 
String sql="select serviceAddress,versions,size from t_version where invalid=0";
    Session session=super.getHibernateTemplate().getSessionFactory().getCurrentSession();
    Query query=session.createSQLQuery(sql);
    query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
    Version ve=new Version();
    Map<String,String> map= (Map<String, String>) query.uniqueResult();

 

能夠直接獲取save or update 後的主鍵值
 
hibernate 映射配置:
單方的配置:
記得在多的一方去掉:
 
在一的一方配置:
在多的一方配置:
hbm.xml配置文件裏面的類型都爲hibernate的類型,須要小寫,如Integer,應該爲integer
one-to-one 時不須要配置column,不然會提示如下錯誤:
 必須爲元素類型 "one-to-one" 聲明屬性 "column"。

object references an unsaved transient instance - save the transient instance before flushing
出現這個問題的緣由是,保存對象的時候,對象中的對象,在保存對象中的引用(僅是ID的時候)這個對象的對象不爲空,可是這個對象的對象的Id卻爲空,因此會致使找不到Id的錯誤,由於對象的對象從數據庫查詢出來是遊離狀態的,當保存的時候...或者是說hibernate不容許保存沒有主鍵的對象!
 
select gcr.id  From GesCustomerReserve gcr left join gcr.user u with u.invalid = 0 where gcr.invalid = 1 
select gescustome0_.id as col_0_0_ from base_customer_reserve gescustome0_ left outer join u_user user1_ on gescustome0_.user_id=user1_.id and (user1_.invalid=0) where gescustome0_.invalid=1 and gescustome0_.id=?
with後面只能跟上一個條件,不然會出現以下錯誤:with-clause referenced two different from-clause elements

 

這種方式,會在對象查詢結束後生成一條單獨的查詢關聯對象的sql語句,不一樣於case when的一條關聯全部內聯,initialize能夠實現間接的左關聯方式查詢html

 
list有多層屬性關聯的時候,用這種方式。
若是實體查詢用到了left,則會爲每一個left的實體生成獨立的sql語句並對應於對象,結果list獲得object泛型數組,object中包含若干對象
 
在left的過程當中,若是左關聯致使的爲空的一項做爲查詢條件,原本就會查詢不出致使主表無數據顯示,因此,條件查詢中儘管用
 
gc.ooo.xxx便可!
 
record:
       //左關聯並不必定要用於select中
        //list中包含三個,customer shop operator
        List<GesCustomer> temList =new ArrayList<GesCustomer>();
 
could not initialize proxy - no Session
檢查下有沒有加@transactional
另外,這個主要是須要獲取關聯的對象,可是想去獲取,但是根本沒有取得操做,通常的加上Hibernate.init ,或其它操做便可
這是一個精典的問題:
由於咱們在hibernate裏面load一個對象出來時,用到的是代理對象,也就是說當咱們在執行load方法時並無發sql語句,而是返回一個proxy對象。只有當們具體用到哪一個get**方法時纔會發sql語句,纔會去數據庫查。可是當咱們把打開session,關閉session交給了srping去作時,當們load完以後咱們的session就會被srping關閉,若是咱們在jsp頁面或者其它的地方再去用get方法取值時就會報這個錯誤。
解決方法一:但若是咱們在hibernate用get方法就能夠解決取單個對象的問題,由於get方法直接發sql語句,把咱們想的數據從數據庫中get出來而後放在內存中。
若是咱們取單個對象能夠用get方法沒有問題;可是若是咱們取的的對象還有關聯對象時用get就有問題,由於它不會把關聯的對象取出來,但若是頁面上用到關聯的對象時也會報no session的問題
解決方法二:用到srping的filter(要加在strutsfilter有前面,由於它也有前後順序,有先進先出的原則)
在咱們的web.xml裏面加上
<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
這樣作就是讓opensession closesession全交給視圖部分,最後視圖部分用完了session再去關session就不會有上面的錯誤了
 
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance 
 
before flushing: com.gjw.entity.building.GesBuilding
通常這種狀況是由於保存時從數據庫中獲取的遊離對象中的對象不爲空,可是其ID卻爲空。
 
Could not read entity state from ResultSet : EntityKey
是由於數據庫的字段與實體的屬性不匹配,好比實體中應該是manyto,而數據庫中是varchar
 
hibernate查詢過濾:
一個老師教許多學生,一個學生被許多老師教,一個學生有好多書,同一種書被許多同窗擁有. 
要查詢教擁有書"a"的學生的老師!HQL如何寫呀?如何取值? 
class teacher{ 
String id; 
String name; 
Set students; 
class student{ 
String id; 
String name; 
Set teachers; 
Set books; 
class book{ 
String id; 
String name; 
Set students; 
}
 
 
 
================================
 
這種寫法(t.students)確定是能夠的,你試試 
SELECT t FROM teacher t join t.students s join s.books b where b.name = 'a'
 
================================
 
SELECT t FROM teacher t where t.students.books.name = 'a'   
 
首先students.books這裏,students是集合,因此這個表達式是確定不對的 
同理books.name也不對
 
================================
 
SELECT t FROM Teacher t,Student s,Book b where s.id in elements(t.students) and b.id in elements(s.books) 
這種方法沒有出錯!不過這種方式要用子查詢!
 
================================
 
是的,element(Set)和indice(List)均可以取集合中的元素,但用在where子句的條件是須要數據庫支持子查詢,mysql就不行 
 
另外t.students s中s並非集合的意思,而是t的students對象的表別名,join t.students s這個hql,hibernate會翻譯成兩個表的內鏈接關
 
 
================另外一篇文章,和上面的結合就ok了================
 
 今天在作一個項目須要作到Set集的數據過慮,由於在獲取一個User的時候不能將屬於這個User的Knowledge所有取出,再一個一個地篩選符
 
合條件的Knowledge,這樣作會在很大的程度降底系統性能。 
 
在 Hibernate中類型爲Set、List的實體屬性也是能夠鏈接查詢的,例如User裏面有一個Set<Knowledge> knowledge屬性要獲取User中
 
Knowledge的isShared的屬性爲true的User而且在返回的User中的knowledges 中包含isShared爲true的Knowledge對象的時候,就要通Set的
 
過慮查詢(左鏈接查詢),在hibernate3.2.3之後的寫法如 下: 
select distinct u from User u left join fetch u.knowledges k where k.isShare=true。 
這樣就只會獲取knowledge的isShared爲true的User,而且User裏面的knowleges中包含knowledge的isShared爲true的Knowlege對象。 
需 要注意的是:關鍵字distinct和fetch。要實現上面的數據過慮就得要這兩個關鍵字。第一個關鍵字是獨立的意思,第二個關鍵字是以一
 
條sql語句 執行。若是少了fetch這個關鍵字,則達不到目的。返回的結果是一個User包含isShared爲true和false的knowledge集合。 
 
同理,若是Knowledge裏面還要Set、List屬性,而且也要據根這些屬性中的對象的某些屬性約束查詢的話(二級或三級鏈接查詢),也是一
 
樣能夠作到的。
 
object references an unsaved transient instance - save the transient instance before flushing: com.gjw.entity.area.GesArea
 
這個問題是因爲保存的時候對象的id爲空,可是這個對象不爲空
 
query.uniqueResult(); 
關於uniqueresult的問題:
在保證只返回一行數據的時候才能使用,例如count的時候。
另外createsqlquery不能使用from entity的方式查詢
 
若是<prop key="hibernate.hbm2ddl.auto">create</prop>不能生成數據庫表,
  1. <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>  
相關文章
相關標籤/搜索