[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-1869) The MultipleHiloPertablegenerator.class wraps at 2**31-1, but javadoc claims Long.

Stephen Hiley (JIRA) noreply at atlassian.com
Tue Aug 21 21:09:13 EDT 2007


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-1869?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_27902 ] 

Stephen Hiley commented on HHH-1869:
------------------------------------

This is one of those insidious bugs, as it does not blow up at runtime, but instead returns the wrong value.  We were burned by this in our production environment.  The code fix offered by the reporter here is spot on!  The number being loaded into hival from doWorkInNewTransaction() should be a long.  And the following multiplication should be cast for clarity as shown in the attached version.

Offending code:

org.hibernate.id.MultipleHiLoPerTableGenerator

hi = hival * (maxLo+1);

where hival and maxLo are both ints.  The result, hi, is a long.  But that doesn't matter to java when it does the computation.  It computes the result as an int, overflows the max lengh, then casts the result to along.  To fix, one just needs to cast the result explicitely, or change hival to be a long (see bug reporter's code). 

Here's the JUnit test I wrote to prove this.

	@Test public void testIntToLong()
	{
		int hival = 34550207;
		int maxLo = 5000;
		
		long uncastHi = hival * (maxLo + 1);
		long expectedHi = (long) hival * (maxLo + 1);
		
		assertEquals("Wishing these two results matched!", expectedHi, uncastHi);
	}

Yields: junit.framework.AssertionFailedError: Wishing these two results matched! expected:<172785585207> but was:<986893367>

The test fails, demonstrating the bug in the generate() method.  Interestingly, this problem was not duplicated in the TableHiLoGenerator in the same package, in that it sets the return value of the super.generate() as a long.

long val = ( (Number) super.generate(session, obj) ).longValue();

But it does suffer from treating that returned hival from the database as an Integer, which will suffer the same truncation problems once your hival grows beyond the max size of a java int.  Perhaps this should be handled as a seperate bug.

> The MultipleHiloPertablegenerator.class wraps at 2**31-1, but javadoc claims Long.
> ----------------------------------------------------------------------------------
>
>                 Key: HHH-1869
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-1869
>             Project: Hibernate3
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 3.2.0 cr1
>         Environment: All versions/all environments.
>            Reporter: Jan Helge Salvesen
>         Attachments: MultipleHiLoPerTableGenerator.zip
>
>
> The returntype of org.hibernate.id.MultipleHiloPertablegenerator.doWorkInCurrentTransaction are Serializable, and the javadoc states that this class shall return a Long (line 26 in source-file). But the value to be returned are, in fact, treated as an Integer and thus limited to 31-bits positive numbers (as an Integer). See line 163 in class, for instance. This behaviour will cause problems for sequence numbers above Integer.MAX_VALUE (that is 2**31-1). When this limit is exceeded, the actual returned  "Long" are a huge-negative integer and may potentinally cause damage. The reason for Priority:Major is the fact that user of this class may have an old-fashon databasescheme, and for this reason, this error may become a "ticking bomb" waiting to a sequence number to exceed 2**31-1.
> The fixup are trivial. The internal representation of the number must be Long, and user shall be urged to upgrade to new release.
> I have attached a fixed version of the MultipleHiloPertablegenerator.java where the generated sequencenumber are treated as a long. I have allso tested my modified version and verified that the sequence-generation part on a Oracle system works as expected, which is that the generated sequence actually can exceed 2**31-1. 
> (I have not tested the schema-generate-part, since this is not critical for user.) 

-- 
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.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list