Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] Failed insert results in invalid cache state

This is pretty advanced stuff, so you may want to reconsider you reasons for
trying to do this in the first place.  You might want to instead catch the
exception in your app and retry the whole transaction, or avoid having
duplicate sequence numbers in the first place (EclipseLink will never
generate duplicates).

To get your exception handler to work, you can't create a copy, as it
violates object identity.  You need to reset the object's pk to null.  You
could use the descriptor to do this generically.


Object value = builder.getSequenceMapping().getAttributeValue(null,
session);
builder.getSequenceMapping().setAttributeValueInObject(dup, value);



bryans wrote:
> 
> Here's what I've got in my ExceptionHandler:
> 
> 
> 
>      public Object handleException(RuntimeException exception) {
> 
> 		if (retry && exception instanceof DatabaseException) {
> 			DatabaseException dbe = (DatabaseException) exception;
> 			if (dbe.getQuery() instanceof InsertObjectQuery) {
> 				InsertObjectQuery insert = (InsertObjectQuery) dbe.getQuery();
> 				Object dup = insert.getObject();
> 				if (dbe.getSession().doesObjectExist(dup)) {
> 					insert.setModifyRow(null);
> 					insert.setPrimaryKey(null);
> 					ObjectBuilder builder = insert.getDescriptor().getObjectBuilder();
> 					ObjectCopyingPolicy policy = new ObjectCopyingPolicy();
> 					policy.setDepth(ObjectCopyingPolicy.CASCADE_ALL_PARTS);
> 					policy.setSession(dbe.getSession());
> 					policy.setShouldResetPrimaryKey(true);
> 					Object clone = builder.copyObject(dup, policy);
>                                         //Change the next sequence value
> 					builder.assignSequenceNumber(clone, dbe.getSession());
> 					insert.setObject(clone);
> 					try {
> 						return dbe.getSession().executeQuery(insert);
> 					} catch	(Throwable t) {
> 						t.printStackTrace();
>                                                 throw t;
> 					}
> 				}
> 			}
> 			
> 		}
> 		throw exception;
> 	}
> 
> 
> 
> There really isn't any way of setting the ID to null as that would assume
> that I know the object's class and can cast it. My attempt here is generic
> to handle any type object, not just predefined ones.
> 
> Everything is done via JPA xml specs with Spring's JpaTemplate to handle
> transaction management logic.
> 
> -B
> 
> 
> James Sutherland wrote:
>> 
>> Definitely a tricky thing to do.  Try not cloning the object, as this
>> will violate object identity, just set its id to null and re-execute the
>> query.
>> 
>> What does your error handler do exactly?
>> 
>> I assume you are using JPA/UnitOfWork?
>> 
>> 
> 
> 


-----
http://wiki.eclipse.org/User:James.sutherland.oracle.com James Sutherland 
http://www.eclipse.org/eclipselink/
 EclipseLink ,  http://www.oracle.com/technology/products/ias/toplink/
TopLink 
Wiki:  http://wiki.eclipse.org/EclipseLink EclipseLink , 
http://wiki.oracle.com/page/TopLink TopLink 
Forums:  http://forums.oracle.com/forums/forum.jspa?forumID=48 TopLink , 
http://www.nabble.com/EclipseLink-f26430.html EclipseLink 
Book:  http://en.wikibooks.org/wiki/Java_Persistence Java Persistence 
-- 
View this message in context: http://www.nabble.com/Failed-insert-results-in-invalid-cache-state-tp25384148p25473634.html
Sent from the EclipseLink - Users mailing list archive at Nabble.com.



Back to the top