[
http://opensource.atlassian.com/projects/hibernate/browse/ANN-683?page=co...
]
Emmanuel Bernard commented on ANN-683:
--------------------------------------
Interesting, IBM, IBM... :)
The problem with your fix is that it does not guarantee a strict order between
FKSecondPass since FK with the same hashCode() value will be randomly ordered. So your fix
is just as bad because it breaks the first contract of the compare(Object, Object)
method.
AnnotationConfiguration hashCode collisions produce random binding
failures
---------------------------------------------------------------------------
Key: ANN-683
URL:
http://opensource.atlassian.com/projects/hibernate/browse/ANN-683
Project: Hibernate Annotations
Issue Type: Bug
Components: binder
Affects Versions: 3.3.0.ga
Environment: Hibernate 3.2.4, J2RE 1.5.0 IBM J9 2.3 AIX ppc-32
j9vmap3223-20070426, AIX 5.3
Reporter: Tim Smith
Priority: Blocker
Fix For: 3.3.1
Attachments: hashCode_bug_fix.patch
Original Estimate: 1 hour
Remaining Estimate: 1 hour
The method AnnotationConfiguration.processFkSecondPassInOrder creates a Comparator that
results in FkSecondPass objects being inadvertently removed from the secondPasses list due
to an incorrect hashCode comparison.
Lines 398 - 401 contain this comparison of hashCodes:
else if ( f1.hashCode() == f2.hashCode() ) {
compare = 0;
}
FkSecondPass uses Object.hashCode which has the JavaDoc comment:
* As much as is reasonably practical, the hashCode method defined by
* class <tt>Object</tt> does return distinct integers for distinct
* objects. (This is typically implemented by converting the internal
* address of the object into an integer, but this implementation
* technique is not required by the
* Java<font size="-2"><sup>TM</sup></font>
programming language.)
In my application I have seen random failures during startup of the application due to
the fact that hashCodes for two FkSecondPass instances are the same, the result is that
the FkSecondPass.secondPass method is never called and the FK is never bound, resulting in
a error like:
org.hibernate.MappingException: Foreign key (FK76A5E7CBCC5EDAA3:CLIENT [])) must have
same number of columns as the referenced primary key (CLIENTAPPRC98BF18C [OBJECTID])
at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:90)
at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:73)
at
org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1263)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1170)
at
org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:316)
at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1115)
at
org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1269)
at
org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:150)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:888)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:416)
at
org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:126)
As you can see the FK column on the owning table is empty (as TableBinder.bindFk is not
called).
This is a blocker for my application as I can not guarantee when the application will
boot. It is entirely dependent on the memory state and implementation of the JVM as to
whether or not a hashCode collision occurs.
The patch is simple, a one-liner, to replace the hashCode comparison with an object
equality comparison:
else if ( f1 == f2 ) {
compare = 0;
}
I have attached a patch for AnnotationConfiguration to fix this issue.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira