[hibernate-dev] HHH-8999/HHH-10413 and Comparable IDs

Gail Badner gbadner at redhat.com
Thu Mar 3 02:49:16 EST 2016


ExecutableList#add attempts to keep track of whether the Executable objects
are sorted. [1]

Except for entity insert actions (which use InsertActionSorter),
ExecutableList#add uses the following to determine if adding the current
Executable to the end invalidates the sort:

if ( previousLast != null && previousLast.compareTo( executable ) > 0 ) {
    sorted = false;
}

EntityAction#compareTo compares the IDs for the current and previous
EntityAction if they have different entity names; similarly,
CollectionAction compares the collection keys for the current and previous
CollectionAction if they have different entity names.

In most cases, the ID class implements Comparable, although I don't know of
any requirement that says this needs to be true.

This breaks down when a byte[] ID is used as described by HHH-8999. The
reason is that AbstractTypeDescriptor#comparator is null because it is
assigned like this:

this.comparator = Comparable.class.isAssignableFrom( type )
        ? (Comparator<T>) ComparableComparator.INSTANCE
        : null;

PrimitiveByteArrayTypeDescriptor does not override
AbstractTypeDescriptor#getComparator, so null is returned ultimately
causing a NullPointerException in AbstractStandardBasicType#compare:

public final int compare(Object x, Object y) {
    return javaTypeDescriptor.getComparator().compare( (T) x, (T) y );
}

The same happens for PrimitiveCharacterArrayTypeDescriptor,
ByteArrayTypeDescriptor, and CharacterArrayTypeDescriptor. Are there others?

According to HHH-10413, this also affects version attributes.

Here are a couple of alternatives:

A) create comparators for PrimitiveCharacterArrayTypeDescriptor,
ByteArrayTypeDescriptor, and CharacterArrayTypeDescriptor.

B) Change AbstractTypeDescriptor#comparator to:

this.comparator = Comparable.class.isAssignableFrom( type )
        ? (Comparator<T>) ComparableComparator.INSTANCE
        : IncomparableComparator.INSTANCE;

IncomparableComparator#compare always returns 0, so that comparison would
never invalidate the sort.

Does it make sense to sort Executable objects by an ID or collection key
that is an array? In other words, would such IDs be generated in a natural
order? If not, I think B) makes more sense.

Thoughts?

Thanks,
Gail

[1]
https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/engine/spi/ExecutableList.java#L194


More information about the hibernate-dev mailing list