Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » CommitManager.sort not working if primary key is a byte array(Getting comparable error deleting entity if PK is a byte array)
CommitManager.sort not working if primary key is a byte array [message #1796358] Thu, 11 October 2018 14:56 Go to next message
Kelvin Nicholls is currently offline Kelvin NichollsFriend
Messages: 1
Registered: October 2018
Junior Member
I am using the latest version of ecliplselink.

I am also using Netbeans 8.1 to generate entities from my table objects in an Oracle 11g database.

The primary key on the database table is of type RAW(36) as it holds a uuid generated value;

The java class generated by Netbeans created a primary key field as a byte array (byte[]).

I have no trouble updating or creating entities. However I get an error when I try to delete.

I have tracked this down to an issue with CommitManager.sort().

It creates a TreeMap object to hold the primary keys of all of the entities it is going to delete in order to sort them later.

The problem is with this line

sortedObjects.put(objectBuilder.extractPrimaryKeyFromObject(objectToDelete, session), objectToDelete);


As the key to a Map is unique any call to put checks to see if the key passed already exists. TreeMap checks to see if the passed key already exists by using the compare method. However this checks to see if the passed key implements the Comparable interface. As arrays do not implement interfaces and need to be compared using Arrays.equals an exception is generated...

java.lang.ClassCastException: [B cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1290)
at java.util.TreeMap.put(TreeMap.java:538)
at org.eclipse.persistence.internal.sessions.CommitManager.sort(CommitManager.java:353)
at org.eclipse.persistence.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:314)
at org.eclipse.persistence.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:285)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1444)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
Caused: javax.persistence.RollbackException
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:157)

Is this a bug in CommitManager or should I not be using byte arrays to hold primary keys?
Re: CommitManager.sort not working if primary key is a byte array [message #1803386 is a reply to message #1796358] Wed, 27 February 2019 18:08 Go to previous message
Eduardo Garcia is currently offline Eduardo GarciaFriend
Messages: 2
Registered: August 2018
Junior Member
I deal with UUID by using String as property type (having byte[] or raw in DB), and with helpers like custom made converters and sequencers (UUIDAttributeConverter, UUIDSequence), I was able to generate a UUID at insert time, after some work.

About deleting part, I had same issues as you are reporting, using String as primary key (UUID), and storing key as byte[] in database, not being able to delete by using EntityManager.remove(object):

java.lang.ClassCastException: [B cannot be cast to java.lang.Comparable


I found a work-around by using createCriteriaDelete as follow:

Considering i'm passing "ido" as the key of the object to remove (String in my case), this is how I delete a row for this scenario:

	
        em.getTransaction().begin();
       	CriteriaBuilder cb = em.getCriteriaBuilder();
       	CriteriaDelete<MyEntityClass> q = cb.createCriteriaDelete(MyEntityClass.class);
       	Root<MyEntityClass> root = q.from(MyEntityClass.class);
       	q.where(cb.equal(root.get(MyEntityClass_.identry),ido));
       	em.createQuery(q).executeUpdate();
	em.getTransaction().commit();


I hope this trick help someone else having same issue.
Previous Topic:Eclipse link connectivity with mysql
Next Topic:EclipseLink does not see created tables in H2 DB
Goto Forum:
  


Current Time: Thu Apr 25 20:54:40 GMT 2024

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

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

Back to the top