Hibernate中常見的20個問題(1-10)

轉自:http://blog.sina.com.cn/s/blog_3f195d25010009r4.html

1問:Hibernate初始化時總是報錯:java.lang.NoClassDefFoundError

Hibernate初始化時出現出錯代碼:

java.lang.NoClassDefFoundError: net/sf/ehcache/CacheException

答:這是新手常見問題。是因爲使用默認設置時,Hibernate文檔裏指出的Hibernate庫不完整,缺少ehcache.jar(用於支持Ehcache的相關文件)。配置中加入以上文件,就可以避免初始化時出現java.lang.NoClassDefFoundError:net/sf/ehcache/CacheException異常。

 

2問:Hibernate報錯:"Not binding factory to JNDI, no JNDI name configured"運行下列程序:

public static void main(String[] args) throws Exception {

      Configuration conf = new Configuration().addClass(Person.class);

......

出現錯誤碼:

12:15:34,250  INFO SessionFactoryObjectFactory:82 - Not binding factory to JNDI, no JNDI name configured

java.lang.UnsupportedOperationException: The user must supply a JDBC connection

at net.sf.Hibernate.connection.UserSuppliedConnectionProvider.getConnection (UserSuppliedConnectionProvider.java:32)

at net.sf.Hibernate.impl.BatcherImpl.openConnection(BatcherImpl.java:289)

at net.sf.Hibernate.impl.SessionImpl.connect(SessionImpl.java:3361)

at net.sf.Hibernate.impl.SessionImpl.connection(SessionImpl.java:3321)

at net.sf.Hibernate.impl.BatcherImpl.prepareQueryStatement(BatcherImpl.java:66)

at net.sf.Hibernate.loader.Loader.prepareQueryStatement(Loader.java:779)

at net.sf.Hibernate.hql.QueryTranslator.iterate(QueryTranslator.java:864)

at net.sf.Hibernate.impl.SessionImpl.iterate(SessionImpl.java:1618)

at net.sf.Hibernate.impl.QueryImpl.iterate(QueryImpl.java:27)

at com.Hibernate.person.TestQueryPerson.main(TestQueryPerson.java:28)

Exception in thread "main"

答:修改main函數,爲該程序指定配置文件即可。

public static void main(String[] args) throws Exception {

      File file=new File("./Hibernate.cfg.xml");

      Configuration conf = new Configuration().configure(file);

......

配置文件如下。

<?xml version="1.0"?>

<!DOCTYPE Hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://Hibernate.sourceforge.net/Hibernate-mapping-3.0.dtd">

<!--

   This mapping demonstrates content-based discrimination for the

   table-per-hierarchy mapping strategy, using a formula

   discriminator.

-->

<Hibernate-mapping package="org.Hibernate.test.array">

   <class name="A" lazy="true">

     <id name="id">

        <generator class="native"/>

     </id>

     <array name="bs" cascade="all" fetch="join">

       <key column="a_id"/>

       <list-index column="idx"/>

        <one-to-many class="B"/>

     </array>

  </class>

  <class name="B" lazy="true">

    <id name="id">

       <generator class="native"/>

    </id>

  </class>

</Hibernate-mapping>

 

3問:使用開發工具Elipse,運行時總報java.lang.NoClassDefFoundError: org/ Hibernate/Session異常

使用Elipse,所用包是hibernte 3,發現在Action中每次執行到:

session=HibernateSessionFactory.currentSession();

時,出現java.lang.NoClassDefFoundError: org/Hibernate/Session異常,如下:

java.lang.NoClassDefFoundError: org/Hibernate/Session

           Hibernate3.Hibernate.ExcuteClass.search(ExcuteClass.java:17)

           Hibernate3.Hibernate.ExcuteClass.test3(ExcuteClass.java:13)

           Hibernate3.Hibernate.Svlt.doGet(Svlt.java:50)

           javax.servlet.http.HttpServlet.service(HttpServlet.java:689)

           javax.servlet.http.HttpServlet.service(HttpServlet.java:802)[/b]

答:這是初學者常見問題,原因是沒有導入hibernate 3.jar包,雖然把hibernate 3.jar寫入了Classpath,但部署的時候卻沒有拷貝到lib下面,可以手動拷貝進入。

 

4問:執行如下方法時,發生"No CurrentSessionContext configured"錯誤

執行如下方法時,發生"No CurrentSessionContext configured"錯誤

Public static Session currentSession() {

try {

     System.out.println("HibernateUtil.currentSession() - start");

     return getSessionFactory().getCurrentSession();

} catch (HibernateException ex) {

     System.out.println("HibernateUtil.currentSession() - failed due to " + ex);

     throw ex;

     }

}

答:這個錯誤是由配置文件引起。在集成Hibernate的環境下(例如Jboss),在session-factory段加入:

<property name="Hibernate.current_session_context_class">jta</property>

在不集成Hibernate的環境下(例如使用JDBC的獨立應用程序),在session-factory段加入:

<property name="Hibernate.current_session_context_class">thread</property>

就可以解決這個問題。

 

5問:移植Jboss 4下配置Hibernate出錯

在Tomcat 5下配置Hibernate成功,但移植到Jboss 4下出現了很多問題。已在deploy目錄下放置了Hibernate-service.xml和Hibernate.cfg.xml文件,但啓動服務器仍然報錯   如下。

16:56:54,046 ERROR [URLDeploymentScanner] Incomplete Deployment listing:

Packages waiting for a deployer:

org.Jboss.deployment.DeploymentInfo@24bd343 { url=file:/C:/Downloads/temp/Jboss-

4.0.0/server/default/deploy/Hibernate.cfg.xml }

deployer: null

status: null

state: INIT_WAITING_DEPLOYER

watch: file:/C:/Downloads/temp/Jboss-4.0.0/server/default/deploy/Hibernate.cfg

.xml

altDD: null

lastDeployed: 1113987414046

lastModified: 1113987414046

mbeans:

Incompletely deployed packages:

org.Jboss.deployment.DeploymentInfo@24bd343 { url=file:/C:/Downloads/temp/Jboss-

4.0.0/server/default/deploy/Hibernate.cfg.xml }

deployer: null

status: null

state: INIT_WAITING_DEPLOYER

watch: file:/C:/Downloads/temp/Jboss-4.0.0/server/default/deploy/Hibernate.cfg

.xml

altDD: null

lastDeployed: 1113987414046

lastModified: 1113987414046

mbeans:

答:這是在Jboss中使用Hibernate的常見問題。在Jboss的某個war包中使用Hibernate應該將Hibernate.cfg.xml文件放置到%war_dir%WEB-INF/classes中,但是Hibernate的factory仍然可能會提示Hibernate.cfg.xml not found。此問題解決方法如下。

由於Jboss已經集成了Hibernate,在deploy\lib文件夾中hibernate2.jar的文件已經存在了一個jar包,所以實際的war中可能使用了shar的hibernate2.jar,由於ClassLoader只會在hibernate2.jar的同級及上級目錄中尋找hibernate.cfg.xml,所以導致Hibernate並沒有去查找%war_dir%WEB-INF/classes中的Hibernate.cfg.xml文件。刪除deploy/lib下的hibernate2.jar或者使用絕對路徑指定Hibernate.cfg.xml可以解決。

除非有其他需求,否則在Jboss下部署Hibernate與在Tomcat下是一樣的,並不需要加其他配置文件。

 

6問:到底在哪裏使用cascade="..."?

答:cascade屬性並不是多對多關係一定要用的,用了它只是插入或刪除對象時更方便一些,只要在cascade的源頭上插入或刪除,所有cascade的關係就會被自動插入或刪除。其中unsaved-value是個很重要的屬性,Hibernate是通過這個屬性來判斷這個對象應該“save”還是“update”,如果這個對象的id是unsaved-value,那說明這個對象不是persistence object,要save(insert);如果id是非unsaved-value,那說明這個對象是persistence object(數據庫中已存在),只要update就行了。

 

7問:到底在哪裏使用inverse="true"?

答:inverse屬性默認是false,就是說關係的兩端都來維護關係。這個意思就是說,如有3個表:Student、Teacher和TeacherStudent,Student對象和Teacher對象是多對多關係,這個關係由TeacherStudent表來表現。

那麼什麼時候插入或刪除TeacherStudent表中的記錄呢。用Hibernate時,不會顯式的對TeacherStudent表操作,對TeacherStudent的操作是Hibernate自動做的。Hibernate就是hbm文件中指定的是“誰”維護關係,在插入或刪除時,就會觸發對關係表的操作。前提是“誰”這個對象已經知道這個關係,就是說關係另一頭的對象已經set或是add到“誰”這個對象裏來。

前面說過inverse默認是false,就是關係的兩端都維護關係,對其中任一個操作都會觸發對錶的操作。當在關係的一頭,如Student中的bag或set中用了inverse="true"時,就代表關係是由另一端維護的(Teacher)。就是說當插入Student時,不會操作TeacherStudent表,即使Student已經知道了關係。只有Teacher插入或刪除時纔會觸發對關係表的操作。所以,關係的兩頭都用inverse="true"是不對的,會導致任何操作都不觸發對關係表的操作。當兩端都是inverse="false"或是default值時,在代碼中對關係顯式的維護也是不對的,會導致在關係表中插入兩次關係。

 

8問:Cascade和Inverse有什麼區別?

答:可以這樣理解,Cascade定義的是關係兩端對象到對象的級聯關係;而Inverse定義的是關係和對象的級聯關係。

 

9問:在刪除操作時報錯:net.sf.Hibernate.ObjectDeletedException:deleted object would be re-saved by cascade (remove deleted object from associations)

答:要刪除關係的一頭時(如,要刪除一個已經和Student對象有關聯的Teacher對象),當tx.commit()時纔會拋出這個異常。防止出現這個異常的方法如下。

     在Student端不用cascade。

     或是用cascade的話,就顯式的刪除對像中的關係。

     在Teacher端要用cascade。

 

10問:出現net.sf.Hibernate.HibernateException: identifier of an instance of my. MyObject altered from N to N異常

答:這個異常不是多對多關係中常遇到的,但是這個異常的提示容易讓人混淆。這是因爲在Java對象中,id定義和hbm文件的不一樣。如Java中用long,而hbm中用type= "integer"。


發佈了25 篇原創文章 · 獲贊 5 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章