Note: This bug is displayed in read-only format because the product is no longer active in Red Hat Bugzilla.

Bug 1152207

Summary: Can Hibernate ID comparison take ANSI_PADDING into consideration?
Product: [JBoss] JBoss Enterprise Application Platform 6 Reporter: Gary Hu <ghu>
Component: HibernateAssignee: Gail Badner <gbadner>
Status: CLOSED NOTABUG QA Contact: Martin Simka <msimka>
Severity: high Docs Contact:
Priority: high    
Version: 6.4.0CC: msimka, smarlow
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-04-14 20:13:08 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
console.log none

Description Gary Hu 2014-10-13 15:03:42 UTC
Created attachment 946444 [details]
console.log

We've got a customer who runs into an issue related to trailing space existing in the id field of a table. 

They have a legacy database that was created in old version of MS Sql Server. Upon the database creation the ANSI_PADDING option was set ON by default. 
With that option turning on, they have some records in the id field contain trailing space.  
When they try to retrieve the entity from database they pass in the key of the entity without trailing space. Hibernate compares the passed in key with the one in database and realizes they are not equal. As a result, Hibernate throws exception:

Caused by: org.hibernate.HibernateException: identifier of an instance of de.viada.evaluation.entity.ChildEntity was altered from ChildEntityPK [childId=id, secondaryId=secondary] to ChildEntityPK [childId=id  , secondaryId=secondary]
        at org.hibernate.event.internal.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:82)
        at org.hibernate.event.internal.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:194)
        at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:156)
        at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:227)
        at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
        at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
        at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234)
        at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
        at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:112)
        ... 71 more

I've attached the log file for your reference.

The relevant java source codes:

org.hibernate.event.internal.DefaultFlushEntityEventListener.checkId(Object, EntityPersister, Serializable, SessionImplementor)

                        if ( !persister.getIdentifierType().isEqual( id, oid, session.getFactory() ) ) {
                                throw new HibernateException(
                                                "identifier of an instance of " +
                                                persister.getEntityName() +
                                                " was altered from " + id +
                                                " to " + oid
                                        );


org.hibernate.type.ComponentType.isEqual(Object, Object, SessionFactoryImplementor)  which (at somer lower levels) calls:
org.hibernate.internal.util.compare.EqualsHelper.equals(Object, Object)


Is it possible for Hibernate trim the trailing space if it detects the database's ANSI_PADDING option is turned off? Or simply just ignore the trailing space when doing the id comparison here?

Comment 1 Gail Badner 2015-04-14 20:13:08 UTC
Hibernate has no way of knowing about ANSI_PADDING setting. Even if it did, it has no way of knowing which tables pre-dated the current ANSI_PADDING setting (and would be unaffected by the change in setting).

I believe this could be accomplished if the application provides a custom type: http://docs.jboss.org/hibernate/orm/4.2/manual/en-US/html_single/#types-custom