Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » double insert
double insert [message #654159] Mon, 14 February 2011 12:43 Go to next message
Tom Eugelink is currently offline Tom Eugelink
Messages: 807
Registered: July 2009
Senior Member
I have a N-M entity called article2storage with a single number (oid) as the PK and an alternate (unique) key on articlenr and storagenr.

Below is a small program that either adds a relation between 82 and A1/1 or removes it.

Article lArticle = Article.findByPK(82);
Storage lStorage = Storage.findByDescription("A1/1");
Article2Storage lArticle2Storage = Article2Storage.findByArticleStorage(lArticle, lStorage);
if (lArticle2Storage == null)
{
lArticle2Storage = new Article2Storage(lArticle, lStorage);
System.out.println("!!!inserted");
}
else
{
lEntityManager.remove(lEntityManager.merge(lArticle2Storage) );
System.out.println("!!!removed");
}

lEntityManager.getTransaction().begin();
lEntityManager.merge(lArticle);
lEntityManager.getTransaction().commit();

Removing works ok, but inserting results in a double insert.
What I read in the log below is that the article2storage entity is created (Article2Storage@41e301f), and assigned a PK.
Then the transaction is started and article is merged, followed by Article2Storage@41e301f getting another PK. That is strange!
Next two records are inserted in article2storage, triggering the UK.
There is only one EM created...
Clueless. Using Eclipselink 2.0.2.

....
!!!inserted
[EL Finer]: 2011-02-14 13:30:37.221--ClientSession(25978508)--Connection(26562441)- -Thread(Thread[main,5,main])--begin transaction
[EL Finest]: 2011-02-14 13:30:37.221--UnitOfWork(30565714)--Thread(Thread[main,5,mai n])--Merge clone with references nl.reinders.bm.Article@876d&Articlenr=82
[EL Finest]: 2011-02-14 13:30:37.221--UnitOfWork(30565714)--Thread(Thread[main,5,mai n])--Register the object nl.reinders.bm.Storage@156ec1&Storagenr=37111&Description=A1/1
[EL Finest]: 2011-02-14 13:30:37.221--UnitOfWork(30565714)--Thread(Thread[main,5,mai n])--Register the object nl.reinders.bm.Article@876d&Articlenr=82
[EL Finer]: 2011-02-14 13:30:37.237--ClientSession(25978508)--Connection(28816391)- -Thread(Thread[main,5,main])--begin transaction
[EL Finest]: 2011-02-14 13:30:37.237--ClientSession(25978508)--Thread(Thread[main,5, main])--Execute query DataModifyQuery(sql="UPDATE sequence SET seq_count = seq_count + ? WHERE seq_name = ?")
[EL Fine]: 2011-02-14 13:30:37.237--ClientSession(25978508)--Connection(28816391)- -Thread(Thread[main,5,main])--UPDATE sequence SET seq_count = seq_count + ? WHERE seq_name = ?
bind => [1, oidnr]
[EL Finest]: 2011-02-14 13:30:37.237--ClientSession(25978508)--Thread(Thread[main,5, main])--Execute query ValueReadQuery(sql="SELECT seq_count FROM sequence WHERE seq_name = ?")
[EL Fine]: 2011-02-14 13:30:37.237--ClientSession(25978508)--Connection(28816391)- -Thread(Thread[main,5,main])--SELECT seq_count FROM sequence WHERE seq_name = ?
bind => [oidnr]
[EL Finer]: 2011-02-14 13:30:37.237--ClientSession(25978508)--Connection(28816391)- -Thread(Thread[main,5,main])--commit transaction
[EL Finest]: 2011-02-14 13:30:37.237--UnitOfWork(30565714)--Thread(Thread[main,5,mai n])--assign sequence to the object (372,290 -> nl.reinders.bm.Article2Storage@41e301f0&Oidnr=null)
[EL Finer]: 2011-02-14 13:30:37.237--UnitOfWork(30565714)--Thread(Thread[main,5,mai n])--begin unit of work commit
[EL Finest]: 2011-02-14 13:30:37.252--UnitOfWork(30565714)--Thread(Thread[main,5,mai n])--PERSIST operation called on: nl.reinders.bm.Article2Storage@41e301f0&Oidnr=null.
[EL Finer]: 2011-02-14 13:30:37.252--ClientSession(25978508)--Connection(28816391)- -Thread(Thread[main,5,main])--begin transaction
[EL Finest]: 2011-02-14 13:30:37.252--ClientSession(25978508)--Thread(Thread[main,5, main])--Execute query DataModifyQuery(sql="UPDATE sequence SET seq_count = seq_count + ? WHERE seq_name = ?")
[EL Fine]: 2011-02-14 13:30:37.252--ClientSession(25978508)--Connection(28816391)- -Thread(Thread[main,5,main])--UPDATE sequence SET seq_count = seq_count + ? WHERE seq_name = ?
bind => [1, oidnr]
[EL Finest]: 2011-02-14 13:30:37.252--ClientSession(25978508)--Thread(Thread[main,5, main])--Execute query ValueReadQuery(sql="SELECT seq_count FROM sequence WHERE seq_name = ?")
[EL Fine]: 2011-02-14 13:30:37.252--ClientSession(25978508)--Connection(28816391)- -Thread(Thread[main,5,main])--SELECT seq_count FROM sequence WHERE seq_name = ?
bind => [oidnr]
[EL Finer]: 2011-02-14 13:30:37.252--ClientSession(25978508)--Connection(28816391)- -Thread(Thread[main,5,main])--commit transaction
[EL Finest]: 2011-02-14 13:30:37.252--UnitOfWork(30565714)--Thread(Thread[main,5,mai n])--assign sequence to the object (372,291 -> nl.reinders.bm.Article2Storage@41e301f0&Oidnr=null)
[EL Finest]: 2011-02-14 13:30:37.252--UnitOfWork(30565714)--Thread(Thread[main,5,mai n])--Execute query UpdateObjectQuery(nl.reinders.bm.Article@876d&Articlenr=82)
[EL Finest]: 2011-02-14 13:30:37.252--UnitOfWork(30565714)--Thread(Thread[main,5,mai n])--Execute query UpdateObjectQuery(nl.reinders.bm.Storage@156ec1&Storagenr=37111&Description=A1/1)
[EL Finest]: 2011-02-14 13:30:37.268--UnitOfWork(30565714)--Thread(Thread[main,5,mai n])--Execute query InsertObjectQuery(nl.reinders.bm.Article2Storage@d2aaae&Oidnr=372291)
[EL Fine]: 2011-02-14 13:30:37.268--ClientSession(25978508)--Connection(26562441)- -Thread(Thread[main,5,main])--INSERT IGNORE INTO article2storage (oidnr, dwhmodified, lazylock, dwhby, storagenr, articlenr) VALUES (?, ?, ?, ?, ?, ?)
bind => [372291, 2011-02-14 13:30:37.252, 1, 1, 37111, 82]
[EL Fine]: 2011-02-14 13:30:37.268--ClientSession(25978508)--Connection(26562441)- -Thread(Thread[main,5,main])--INSERT IGNORE INTO reindershst:article2storage (oidnr, dwhmodified, lazylock, dwhby, storagenr, articlenr, hstvalidfrom) VALUES (?, ?, ?, ?, ?, ?, ?)
bind => [372291, 2011-02-14 13:30:37.252, 1, 1, 37111, 82, 2011-02-14 13:30:37.268]
[EL Finest]: 2011-02-14 13:30:37.268--UnitOfWork(30565714)--Thread(Thread[main,5,mai n])--Execute query InsertObjectQuery(nl.reinders.bm.Article2Storage@d2aa89&Oidnr=372290)
[EL Fine]: 2011-02-14 13:30:37.268--ClientSession(25978508)--Connection(26562441)- -Thread(Thread[main,5,main])--INSERT IGNORE INTO article2storage (oidnr, dwhmodified, lazylock, dwhby, storagenr, articlenr) VALUES (?, ?, ?, ?, ?, ?)
bind => [372290, 2011-02-14 13:30:37.252, 1, 1, 37111, 82]
[EL Fine]: 2011-02-14 13:30:37.268--ClientSession(25978508)--Connection(26562441)- -Thread(Thread[main,5,main])--INSERT IGNORE INTO reindershst:article2storage (oidnr, dwhmodified, lazylock, dwhby, storagenr, articlenr, hstvalidfrom) VALUES (?, ?, ?, ?, ?, ?, ?)
bind => [372290, 2011-02-14 13:30:37.252, 1, 1, 37111, 82, 2011-02-14 13:30:37.268]
[EL Finer]: 2011-02-14 13:30:37.284--ClientSession(25978508)--Connection(26562441)- -Thread(Thread[main,5,main])--commit transaction
[EL Warning]: 2011-02-14 13:30:37.299--ClientSession(25978508)--Thread(Thread[main,5, main])--Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.0.2.v20100323-r6872): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Unique constraint (informix.article2storage_ak01) violated.
Re: double insert [message #654203 is a reply to message #654159] Mon, 14 February 2011 15:07 Go to previous messageGo to next message
James Sutherland is currently offline James Sutherland
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

What EntityManager are your find methods using? If they are using the same EntityManager, then you should not be calling merge at all.

As you can see in your log you are getting two different Article2Storage objects created from the result of your merge. My guess this is because of how new Article2Storage(lArticle, lStorage); is causing lArticle to have an inverse relationship. What does this method do? You have somehow violated object identity and are registering the same objects twice into the persistence context. Try not using merge, this seems to be causing your issue.



James : Wiki : Book : Blog : Twitter
Re: double insert [message #654217 is a reply to message #654203] Mon, 14 February 2011 15:51 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom Eugelink
Messages: 807
Registered: July 2009
Senior Member
On 14-2-2011 16:07, James wrote:
> What EntityManager are your find methods using? If they are using the same EntityManager, then you should not be calling merge at all.

There is (in this scenario) only one singleton EM. I figured because the EM was queries outside the transaction, I needed to merge it inside. Hm. I need to reread some documentation.

> As you can see in your log you are getting two different Article2Storage objects created from the result of your merge. My guess this is because of how new Article2Storage(lArticle, lStorage); is causing lArticle to have an inverse relationship. What does this method do?

Indeed, it calls setArticle, which calls addArticle2Storage on article again, building up a two-way relation.

> You have somehow violated object identity and are registering the same objects twice into the persistence context. Try not using merge, this seems to be causing your issue.

You are right, removing "merge" does indeed solve the problem.
I'm a bit confused though; even if the entity is already part of the persistence contents, why should adding the same object (with the same hashcode/memory address so to speak) cause in a double instance of it?
Should I examine my equals() method to make sure it is seen as equal?

Tom
Re: double insert [message #654828 is a reply to message #654217] Thu, 17 February 2011 10:31 Go to previous message
Tom Eugelink is currently offline Tom Eugelink
Messages: 807
Registered: July 2009
Senior Member
> You are right, removing "merge" does indeed solve the problem.
> I'm a bit confused though; even if the entity is already part of the persistence contents, why should adding the same object (with the same hashcode/memory address so to speak) cause in a double instance of it?

Aha! I forgot! In the application I do a EM.clear before the begin, to clear any stuff that may have been hanging around from a previous persist attempt. Pfew.
Previous Topic:Error in implementation(?): Calling Stored Procedures in FireBird 2.1
Next Topic:Left Outer Join With Curly Brackets
Goto Forum:
  


Current Time: Sun Oct 26 01:53:33 GMT 2014

Powered by FUDForum. Page generated in 0.02147 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software