Hibernate錯誤:org.hibernate。NonUniqueObjectException:具有相同標識符值的不同對象已經與會話關聯

[英]Hibernate Error: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session


I have two user Objects and while I try to save the object using

我有兩個user對象,而我嘗試使用它來保存對象。

session.save(userObj);

I am getting the following error:

我得到了以下錯誤:

Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:
[com.pojo.rtrequests.User#com.pojo.rtrequests.User@d079b40b]

I am creating the session using

我正在使用

BaseHibernateDAO dao = new BaseHibernateDAO();          

rtsession = dao.getSession(userData.getRegion(),
                           BaseHibernateDAO.RTREQUESTS_DATABASE_NAME);

rttrans = rtsession.beginTransaction();
rttrans.begin();

rtsession.save(userObj1);
rtsession.save(userObj2);

rtsession.flush();
rttrans.commit();

rtsession.close(); // in finally block

I also tried doing the session.clear() before saving, still no luck.

我也試過了,在存錢之前,還是沒有運氣。

This is for the first I am getting the session object when a user request comes, so I am getting why is saying that object is present in session.

這是我第一次在用戶請求時獲得會話對象,所以我得到了為什么說這個對象在會話中。

Any suggestions?

有什么建議嗎?

33 个解决方案

#1


157  

I have had this error many times and it can be quite hard to track down...

我犯過很多次這樣的錯誤,很難找到……

Basically, what hibernate is saying is that you have two objects which have the same identifier (same primary key) but they are not the same object.

基本上,hibernate的意思是兩個對象具有相同的標識符(相同的主鍵),但它們不是相同的對象。

I would suggest you break down your code, i.e. comment out bits until the error goes away and then put the code back until it comes back and you should find the error it.

我建議您將代碼分解,即注釋掉位,直到錯誤消失,然后將代碼返回,直到它返回,您應該找到錯誤。

It most often happens via cascading saves where there is a cascade save between object A and B, but object B has already been associated with the session but not on the same instance of B.

在對象a和B之間存在級聯保存時,這種情況最常見,但是對象B已經與會話相關聯,但是在相同的實例B上沒有。

What primary key generator are you using?

您使用的主鍵生成器是什么?

The reason I ask is this error is related to how you're telling hibernate to ascertain the persistent state of an object (i.e. whether an object is persistent or not). The error could be happening because hibernate is trying to persist and object that is already persistent. In fact, if you use save hibernate will try and persist that object, and maybe there is already an object with that same primary key associated with the session.

我問這個問題的原因是,這個錯誤與您如何告訴hibernate以確定對象的持久化狀態有關(例如,對象是否持久化)。這個錯誤可能會發生,因為hibernate試圖持久化,而對象已經是持久化的。事實上,如果您使用save hibernate,它將嘗試並持久保存該對象,並且可能已經有一個對象具有與會話相關聯的相同的主鍵。

Example

例子

Assuming you have a hibernate class object for a table with 10 rows based on a primary key combination (column 1 and column 2). Now, you have removed 5 rows from the table at some point of time. Now, if you try to add the same 10 rows again, while hibernate tries to persist the objects in database, 5 rows which were already removed will be added without errors. Now the remaining 5 rows which are already existing, will throw this exception.

假設您有一個hibernate類對象,針對一個基於主鍵組合(列1和列2)的表,有10行。現在,如果您嘗試再次添加相同的10行,而hibernate試圖將對象持久化到數據庫中,那么已經刪除的5行將會被添加而不會出現錯誤。現在已經存在的其余5行將拋出這個異常。

So the easy approach would be checking if you have updated/removed any value in a table which is part of something and later are you trying to insert the same objects again

所以最簡單的方法是檢查是否更新或刪除了表中的任何值,這些值是某個值的一部分,然后再插入相同的對象

#2


15  

This is only one point where hibernate makes more problems than it solves. In my case there are many objects with the same identifier 0, because they are new and don't have one. The db generates them. Somewhere I have read that 0 signals Id not set. The intuitive way to persist them is iterating over them and saying hibernate to save the objects. But You can't do that - "Of course You should know that hibernate works this and that way, therefore You have to.." So now I can try to change Ids to Long instead of long and look if it then works. In the end it's easier to do it with a simple mapper by your own, because hibernate is just an additional intransparent burden. Another example: Trying to read parameters from one database and persist them in another forces you to do nearly all work manually. But if you have to do it anyway, using hibernate is just additional work.

這只是hibernate造成的問題多於它解決的問題的一點。在我的例子中,有許多具有相同標識符為0的對象,因為它們是新的,沒有標識符。db生成它們。在某個地方,我讀到0個信號沒有設置。保存它們的直觀方法是遍歷它們並說hibernate保存對象。但是你不能那樣做——“當然你應該知道hibernate是這么工作的,所以你必須…”所以現在我可以嘗試把id改成Long而不是Long然后看看它是否有效。最后,使用一個簡單的映射器來實現它更容易,因為hibernate只是一個額外的不透明負擔。另一個例子是:嘗試從一個數據庫讀取參數,並將它們持久化到另一個數據庫中,這將迫使您幾乎手工完成所有工作。但是如果您不得不這樣做,使用hibernate只是額外的工作。

#3


12  

USe session.evict(object); The function of evict() method is used to remove instance from the session cache. So for first time saving the object ,save object by calling session.save(object) method before evicting the object from the cache. In the same way update object by calling session.saveOrUpdate(object) or session.update(object) before calling evict().

使用session.evict(對象);expt()方法的功能用於從會話緩存中刪除實例。因此,第一次保存對象時,通過調用session.save(object)方法保存對象,然后將對象從緩存中移除。以同樣的方式更新對象,在調用rejt()之前調用session.saveOrUpdate(object)或session.update(object)。

#4


6  

As somebody already pointed above i ran into this problem when i had cascade=all on both ends of a one-to-many relationship, so let's assume A --> B (one-to-many from A and many-to-one from B) and was updating instance of B in A and then calling saveOrUpdate(A) , it was resulting in a circular save request i.e save of A triggers save of B that triggers save of A... and in the third instance as the entity( of A) was tried to be added to the sessionPersistenceContext the duplicateObject exception was thrown.
  I could solve it by removing cascade from one end.

正如上面有人已經指出的我遇到這個問題當我有級聯=所有兩端的一對多的關系,所以我們假設——> B(一對多和多對一的從B)和B的更新實例,然后調用saveOrUpdate(a),它所產生的循環保存請求我。保存一個觸發器保存一個觸發器保存一個觸發器保存一個觸發器保存一個。在第三個實例中,當嘗試將實體(A)添加到sessionPersistenceContext中時,就拋出了duplicateObject異常。我可以通過從一端移除級聯來解決它。

#5


6  

This can happen when you have used same session object for read & write. How? Say you have created one session. You read a record from employee table with primary key Emp_id=101 Now You have modified the record in Java. And you are going to save the Employee record in database. we have not closed session anywhere here. As the object that was read also persist in the session. It conflicts with the object that we wish to write. Hence this error comes.

當您對讀寫使用了相同的會話對象時,可能會發生這種情況。如何?假設您已經創建了一個會話。您使用主鍵Emp_id=101從employee表中讀取一條記錄,現在您已經在Java中修改了該記錄。將員工記錄保存在數據庫中。我們這里沒有非公開會議。因為被讀取的對象也在會話中保持不變。它與我們想要寫的對象沖突。因此這個錯誤。

#6


3  

Get the object inside the session, here an example:

在會話中獲取對象,這里有一個例子:

MyObject ob = null;
ob = (MyObject) session.get(MyObject.class, id);

#7


3  

I ran into this problem by:

我遇到這個問題的原因是:

  1. Deleting an object (using HQL)
  2. 刪除對象(使用HQL)
  3. Immediately storing a new object with the same id
  4. 立即存儲具有相同id的新對象

I resolved it by flushing the results after the delete, and clearing the cache before saving the new object

我通過在刪除后刷新結果並在保存新對象之前清除緩存來解決這個問題

String delQuery = "DELETE FROM OasisNode";
session.createQuery( delQuery ).executeUpdate();
session.flush();
session.clear();

#8


2  

I also ran into this problem and had a hard time to find the error.

我也遇到了這個問題,很難找到錯誤。

The problem I had was the following:

我遇到的問題是:

The object has been read by a Dao with a different hibernate session.

對象由具有不同hibernate會話的Dao讀取。

To avoid this exception, simply re-read the object with the dao that is going to save/update this object later on.

為了避免此異常,只需使用dao重新讀取對象,該對象將在稍后保存/更新該對象。

so:

所以:

class A{      

 readFoo(){
       someDaoA.read(myBadAssObject); //Different Session than in class B
    }

}

class B{



 saveFoo(){
       someDaoB.read(myBadAssObjectAgain); //Different Session than in class A
       [...]
       myBadAssObjectAgain.fooValue = 'bar';
       persist();
    }

}

Hope that save some people a lot of time!

希望能節省一些人很多時間!

#9


1  

Are your Id mappings correct? If the database is responsible for creating the Id through an identifier, you need to map your userobject to that ..

你的Id映射正確嗎?如果數據庫負責通過標識符創建Id,則需要將userobject映射到它。

#10


1  

Check if you forgot to put @GenerateValue for @Id column. I had same problem with many to many relationship between Movie and Genre. The program threw Hibernate Error: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session error. I found out later that I just have to make sure you have @GenerateValue to the GenreId get method.

檢查是否忘記為@Id列放置@GenerateValue。我對電影和流派之間的關系有很多不同的看法。程序拋出Hibernate錯誤:org.hibernate。NonUniqueObjectException:具有相同標識符值的不同對象已經與會話錯誤關聯。我后來發現,我只需要確保GenreId get方法的@GenerateValue。

#11


1  

just check the id whether it takes null or 0 like

檢查id是否為null或0

if(offersubformtwo.getId()!=null && offersubformtwo.getId()!=0)

in add or update where the content are set from form to Pojo

在add或update中,內容從表單設置到Pojo

#12


1  

I encountered this problem with deleting an object, neither evict nor clear helped.

我在刪除一個對象時遇到了這個問題,既不清除也不清除幫助。

/**
 * Deletes the given entity, even if hibernate has an old reference to it.
 * If the entity has already disappeared due to a db cascade then noop.
 */
public void delete(final Object entity) {
  Object merged = null;
  try {
    merged = getSession().merge(entity);
  }
  catch (ObjectNotFoundException e) {
    // disappeared already due to cascade
    return;
  }
  getSession().delete(merged);
}

#13


1  

I had a similar problem. In my case I had forgotten to set the increment_by value in the database to be the same like the one used by the cache_size and allocationSize. (The arrows point to the mentioned attributes)

我也有類似的問題。在我的例子中,我忘記將數據庫中的increment_by值設置為與cache_size和allocationSize使用的值相同。(箭頭指向上述屬性)

SQL:

SQL:

CREATED         26.07.16
LAST_DDL_TIME   26.07.16
SEQUENCE_OWNER  MY
SEQUENCE_NAME   MY_ID_SEQ
MIN_VALUE       1
MAX_VALUE       9999999999999999999999999999
INCREMENT_BY    20 <-
CYCLE_FLAG      N
ORDER_FLAG      N
CACHE_SIZE      20 <-
LAST_NUMBER     180

Java:

Java:

@SequenceGenerator(name = "mySG", schema = "my", 
sequenceName = "my_id_seq", allocationSize = 20 <-)

#14


1  

I have the same error I was replacing my Set with a new one get from Jackson.

我有同樣的錯誤,我用一個新的從傑克遜得到的。

To solve this I keep the existing set, I remove from the old set the element unknown into the new list with retainAll. Then I add the new ones with addAll.

為了解決這個問題,我保留了現有的集合,我從舊的集合中刪除了包含retainAll的新列表中的未知元素。然后我添加新的與addAll。

    this.oldSet.retainAll(newSet);
    this.oldSet.addAll(newSet);

No need to have the Session and manipulate it.

不需要使用會話並對其進行操作。

#15


1  

Try this. The below worked for me!

試試這個。下面的內容對我很有用!

In the hbm.xml file

hbm。xml文件

  1. We need to set the dynamic-update attribute of class tag to true:

    我們需要將class tag的dynamic-update屬性設為true:

    <class dynamic-update="true">
    
  2. Set the class attribute of the generator tag under unique column to identity:

    將唯一列下的生成器標記的類屬性設置為identity:

    <generator class="identity">
    

Note: Set the unique column to identity rather than assigned.

注意:將唯一列設置為標識,而不是指定。

#16


0  

Another thing that worked for me was to make the instance variable Long in place of long

另一件對我有用的事情是使實例變量Long代替Long


I had my primary key variable long id; changing it to Long id; worked

我有主鍵變量long id;將其更改為Long id;工作

All the best

願一切都好!

#17


0  

You always can do a session flush. Flush will synchronize the state of all your objects in session (please, someone correct me if i'm wrong), and maybe it would solve your problem in some cases.

您總是可以進行會話刷新。刷新將同步會話中所有對象的狀態(如果我錯了,請有人糾正我),在某些情況下,它可能會解決您的問題。

Implementing your own equals and hashcode may help you too.

實現您自己的equals和hashcode也可以幫助您。

#18


0  

You can check your Cascade Settings. The Cascade settings on your models could be causing this. I removed Cascade Settings (Essentially not allowing Cascade Inserts/Updates) and this solved my problem

你可以檢查你的級聯設置。模型上的級聯設置可能導致這種情況。我刪除了級聯設置(本質上不允許級聯插入/更新),這就解決了我的問題

#19


0  

I found this error as well. What worked for me is to make sure that the primary key (that is auto-generated) is not a PDT (i.e. long, int, ect.), but an object (i.e. Long, Integer, etc.)

我也發現了這個錯誤。對我有效的是確保主鍵(即自動生成的)不是PDT(即long、int、ect),而是一個對象(即long、Integer等)。

When you create your object to save it, make sure you pass null and not 0.

當您創建對象來保存它時,確保您傳遞的是null而不是0。

#20


0  

I'm new to NHibernate, and my problem was that I used a different session to query my object than I did to save it. So the saving session didn't know about the object.

我是NHibernate的新手,我的問題是我使用了不同的會話來查詢我的對象,而不是保存它。所以保存會話不知道對象。

It seems obvious, but from reading the previous answers I was looking everywhere for 2 objects, not 2 sessions.

這似乎是顯而易見的,但從閱讀之前的答案來看,我到處尋找兩個對象,而不是兩個會話。

#21


0  

Does this help?

這有幫助嗎?

User userObj1 = new User();
User userObj2 = userObj1;
.
.
.
rtsession.save(userObj1);
rtsession.save(userObj2); 

#22


0  

@GeneratedValue(strategy=GenerationType.IDENTITY), adding this annotation to the primary key property in your entity bean should solve this issue.

@GeneratedValue(strategy=GenerationType.IDENTITY)將此注釋添加到實體bean中的主鍵屬性應該可以解決這個問題。

#23


0  

I resolved this problem .
Actually this is happening because we forgot implementation of Generator Type of PK property in the bean class. So make it any type like as

我解決了這個問題。實際上,這是因為我們忘記了bean類中PK屬性生成器類型的實現。把它做成任何類型

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;

when we persist the objects of bean ,every object acquired same ID ,so first object is saved ,when another object to be persist then HIB FW through this type of Exception: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session.

當我們持久化bean的對象時,每個對象都獲得了相同的ID,因此第一個對象被保存,當另一個對象被持久化時,通過這種類型的異常HIB FW: org.hibernate。NonUniqueObjectException:一個具有相同標識符值的不同對象已經與會話關聯。

#24


0  

I have solved a similar problem like that:

我解決了一個類似的問題:

plan = (FcsRequestPlan) session.load(plan.getClass(), plan.getUUID());
while (plan instanceof HibernateProxy)
    plan = (FcsRequestPlan) ((HibernateProxy) plan).getHibernateLazyInitializer().getImplementation();

#25


0  

before the position where repetitive objects begin , you should close the session and then you should start a new session

在重復對象開始的位置之前,您應該關閉會話,然后啟動一個新的會話

session.close();      
session = HibernateUtil.getSessionFactory().openSession();

so in this way in one session there is not more than one entities that have the same identifier.

因此,在一個會話中,只有一個實體具有相同的標識符。

#26


0  

The problem happens because in same hibernate session you are trying to save two objects with same identifier.There are two solutions:-

問題發生的原因是,在同一個hibernate會話中,您試圖保存兩個具有相同標識符的對象。有兩個解決方案:-

  1. This is happening because you have not configured your mapping.xml file correctly for id fields as below:-

    這是因為您尚未配置映射。正確的xml文件的id字段如下:-

    <id name="id">
      <column name="id" sql-type="bigint" not-null="true"/>
      <generator class="hibernateGeneratorClass"</generator>
    </id>
    
  2. Overload the getsession method to accept a Parameter like isSessionClear, and clear the session before returning the current session like below

    重載getsession方法以接受isSessionClear這樣的參數,並在返回當前會話之前清除會話,如下所示

    public static Session getSession(boolean isSessionClear) {
        if (session.isOpen() && isSessionClear) {
            session.clear();
            return session;
        } else if (session.isOpen()) {
            return session;
        } else {
            return sessionFactory.openSession();
        }
    }
    

This will cause existing session objects to be cleared and even if hibernate doesn't generate a unique identifier ,assuming you have configured your database properly for a primary key using something like Auto_Increment,it should work for you.

這將導致清除現有的會話對象,即使hibernate沒有生成唯一標識符,假設您已經使用Auto_Increment為主鍵正確配置了數據庫,那么它也應該適合您。

#27


0  

One workaround to solve this issue is try to read the object back from hibernate cache/db before you make any updates and then persist.

解決這個問題的一個解決方案是,在進行任何更新之前,嘗試從hibernate緩存/db中讀取對象,然后再進行持久化。

Example:

例子:

            OrderHeader oh = orderHeaderDAO.get(orderHeaderId);
            oh.setShipFrom(facilityForOrder);
            orderHeaderDAO.persist(oh);

Note: Keep in mind that this does not fix the root cause but solves the issue.

注意:請記住,這不是解決問題的根本原因,而是解決問題。

#28


0  

Otherwise than what wbdarby said, it even can happen when an object is fetched by giving the identifier of the object to a HQL. In the case of trying to modify the object fields and save it back into DB(modification could be insert, delete or update) over the same session, this error will appear. Try clearing the hibernate session before saving your modified object or create a brand new session.

Hope i helped ;-)

與wbdarby所說的不同,它甚至可以通過將對象的標識符授予HQL來獲取對象。如果試圖在同一會話中修改對象字段並將其保存回DB(修改可以是插入、刪除或更新),則會出現此錯誤。在保存修改后的對象或創建一個全新的會話之前,嘗試清除hibernate會話。希望我幫助;-)

#29


0  

Late to the party, but may help for coming users -

聚會遲到,但可能有助於未來的用戶-

I got this issue when i select a record using getsession() and again update another record with same identifier using same session causes the issue. Added code below.

當我使用getsession()選擇一條記錄並再次使用相同的會話使用相同的標識符更新另一條記錄時,我就遇到了這個問題。添加下面的代碼。

Customer existingCustomer=getSession().get(Customer.class,1);
Customer customerFromUi;// This customer details comiong from UI with identifer 1

getSession().update(customerFromUi);// Here the issue comes

This should never be done . Solution is either evict session before update or change business logic.

這是不應該做的。解決方案是在更新或更改業務邏輯之前刪除會話。

#30


0  

You can use session.merge(obj), if you are doing save with different sessions with same identifier persistent object.
It worked, I had same issue before.

如果您正在使用具有相同標識符持久對象的不同會話進行保存,那么可以使用session.merge(obj)。我以前也遇到過同樣的問題。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2009/07/02/392e5044a39b8e9dff40975868261d0a.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com