2011-12-01 64 views
5

我想通過Hibernate映射到MySQL表來實現一些Java對象的持久性。當我提交時,我收到一條消息,說'批量更新返回來自update [0]的意外行計數;實際行數:0;預計:1'。LONG作爲Hibernate映射到MySQL的主鍵

我的假設是,這個問題是由我在我的Java POJO中有一個long字段引起的,我想用它作爲MySQL表中的主鍵。由於我無法在MySQL表中使用數據類型LONG作爲我的主鍵(錯誤1170:密鑰規範中使用的BLOB/TEXT列'id',而且沒有密鑰長度),所以我從一些Google搜索結果和這個post得出結論:BIGINT會是合適的映射爲long。但它不會更新。

我的測試POJO Person很簡單。它有3個字段:id(long),firstname(String),lastname(String)與setter和getters等。

我在xml(person.hbm.xml)中做了hibernate映射,標題):是應該保存或更新記錄是簡單

<hibernate-mapping> 
    <class name="hibernatetest.Person" table="hibernatetest"> 
    <id name="id" type="long" column="id" > 
    <generator class="native"/> 
    </id> 

    <property name="firstname"> 
    <column name="firstname" /> 
    </property> 
    <property name="lastname"> 
    <column name="lastname"/> 
    </property> 
</class> 
</hibernate-mapping> 

我實際的Java代碼片斷:

Transaction tr = session.beginTransaction();    
Person person = new Person(1,"John","Doe"); 
session.saveOrUpdate(person); 
tr.commit(); 

及這裏的東西,這一點,如果我改變的類型的所有作品就好id添加到Person對象和MySQL表中的int(整數)。但是,我沒有這個選擇來解決我想要堅持的實際對象,所以問題在於;我做錯了什麼,或者我該怎麼做才能使它工作?謝謝。

ADDING堆棧跟蹤:

Hibernate: update hibernatetest set firstname=?, lastname=? where id=? 
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1 
    at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:81) 
    at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:73) 
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:57) 
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3006) 
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2908) 
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3237) 
    at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:113) 
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:273) 
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:265) 
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:187) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337) 
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) 
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1082) 
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:317) 
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) 
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175) 
    at com.hibernate.test.TestMain.main(TestMain.java:38) 
nested transactions not supported 

UPDATE: OK,我終於工作了。我將hibernate生成器類從「native」更改爲「assigned」,現在它按預期工作。所以,現在的Hibernate映射的樣子:

<hibernate-mapping> 
    <class name="hibernatetest.Person" table="hibernatetest"> 
    <id name="id" type="long" column="id" > 
    <generator class="assigned"/> 
    </id> 

    <property name="firstname"> 
    <column name="firstname" /> 
    </property> 
    <property name="lastname"> 
    <column name="lastname"/> 
    </property> 
</class> 
</hibernate-mapping> 

必須承認,我不知道該參數(從某處複製)的含義,也不知道它可能會導致此大爲頭痛。發現這是非常有用的explanation

顯然我沒有足夠的憑據來回答我自己的問題,所以我想它會保持開放,或者如果有人提供一個空的答案,我會接受它。謝謝。

+0

你可以發佈你的完整堆棧跟蹤,長期和BIGINT應該工作正常,我已經使用它本人沒有發現問題,請分享你的stacktrace – mprabhat

+0

什麼是你的db列類型定義?而你的id屬性類型?無論如何,Bigint爲列,Long爲java屬性是好事。 – polypiel

+0

@mprabhat完成。它有一條消息說'我不知道嵌套事務不支持',我以前沒有看到。不知道它是什麼意思? – hgus1294

回答

5

當您使用saveOrUpdate()方法休眠觸發插入查詢,如果該對象的ID是nullupdate如果它是任何其他值。我可以看到代碼 Person person = new Person(1,"John","Doe");id設置爲1並調用saveOrUpdate()方法。我假設沒有條目爲id 1,因此錯誤被拋出。

要使其工作,您需要進行以下更改。

  1. 變化id在那種會Longlong(包裝類,以便它可以支持空)。

  2. 編寫構造函數new Person("John","Doe");並保存該對象。

保留交易數據的<generator class="assigned"/>不是一個好主意。相反,當你首先嚐試時,你應該堅持到native

我覺得這是一種更簡潔的方法來解決您的初始問題,即使您找到了替代解決方案。

+0

謝謝。您假設在'SaveOrUpdate'之前沒有'id' = 1的記錄是正確的。我試圖根據您的建議將類類型更改爲「Long」,但如果將生成器設置爲「native」,它將恢復爲相同的錯誤。我沒有理解你第二點,你從構造函數中省略了id? 'id'不是自動生成的ID,所以我需要能夠將其設置爲特定值。 – hgus1294

+0

我的意思是讓你的數據庫選擇ID並且在保存的時候不要硬編碼這個ID。選擇[這裏]選項(http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html#mapping-declaration-id)怎樣才能做到這一點。 – ManuPK

+0

好的,明白了。在我的實際情況中,'id'是從外部服務提供的,需要持久保存,所以我不能讓db決定。如果我只是將類類型更改爲「Long」,並且保留一個構造函數,並使用「Long」,則會得到原始異常。這是否如預期的那樣,還是我誤解了別的東西?您提到交易發生器=「分配」風險。有什麼風險? – hgus1294