DataNucleus - Products
  History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: CORE-3022
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Andy Jefferson
Reporter: John Miller
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
JPOX Core

JPOX caches first available TypeInfo for a SQL datatype yet others may be more appropriate

Created: 11/Oct/06 04:54 PM   Updated: 04/Jul/07 01:50 PM
Component/s: Datastore Support
Affects Version/s: 1.1.1
Fix Version/s: 1.2.0-beta-3, 1.1.8

File Attachments: 1. Zip Archive TypeInfo Defect Files.zip (595 kb)

Environment: Windows XP using a SQL Server 2005 Driver


 Description  « Hide
I am currently running into this strange error when I try and validate my metatdata against my JDO Document.

ERROR: [Failed to generate new Mapping of type org.jpox.store.rdbms.mapping.CharRDBMSMapping, exception : String max length of 45 is outside the acceptable range [0, 36] for column "TRANSACTIONTYPE"
javax.jdo.JDOUserException: String max length of 45 is outside the acceptable range [0, 36] for column "TRANSACTIONTYPE" at org.jpox.store.rdbms.mapping.CharRDBMSMapping.initialize(CharRDBMSMapping.java:191)

------------------------------------------------------------------------------------------------------
In lieu of a JUNIT Test, I have diagnosed the problem thoroughly, and I've found the problem, and I'm hoping that you can take some time to take a look at it.

The problem is in the fundamental way that JPOX is storing the TypeInfo objects in the org.jpox.store.rdbms.adapter.DatabaseAdapter object. JPOX queries that Database MetaData and stores the "first instance" that it looks up for each type.

class: org.jpox.store.rdbms.adapter.DatabaseAdapter
method: createTypeInfo(DatabaseMetaData metadata)
.
                    Integer key = new Integer(ti.dataType);

                    if (typesByTypeNumber.get(key) == null) <<---skips over if key already exists
                    {
                        typesByTypeNumber.put(key, ti);
                    }
.

The problem is that some database Datatypes have multiple variations attached to it, and the code above doesn't take in account if the Driver offers up the Datatype information in a different order.

I came across this problem when testing against the latest SQL Server 2005 Driver. This driver offers up the Datatype information differently than the SQL Server 2000 Driver.

SQL Server 2005 Driver: com.microsoft..sqlserver.jdbc.SQLServerDriver
SQL Server 2000 Driver: com.microsoft.jdbc.sqlserver.SQLServerDriver

I have attached LookupOrderOfTypesByTypeNumber.rtf file that shows the "order" in which the TypeInfos are looked up. I have also attached TypesByTypeNumber.txt, which shows the contents of the DatabaseAdapter's "typesByTypeNumber" instance variable after the lookup was completed for each of the Drivers.

Current Test Case:
I have a database column called TRANSACTIONTYPE and is of type CHAR with length 45. During the JPOX MetaDataValidation, the TypeInfo inside the typesByTypeNumber for datatype=1 (CHAR) is represented by:

1=org.jpox.store.rdbms.typeinfo.MSSQLTypeInfo
  typeName = uniqueidentifier
  jdbcTypeName = Types.CHAR
  dataType = 1
  precision = 36
  literalPrefix = '
  literalSuffix = '
  createParams = null
  nullable = 1
  caseSensitive = false
  searchable = 2
  unsignedAttribute = false
  fixedPrecScale = false
  autoIncrement = false
  localTypeName = uniqueidentifier
  minimumScale = 0
  maximumScale = 0
  numPrecRadix = 0

As you can see, the precision associated with Types.CHAR is only 36 rather than an expected 8000.

Here is the order of the CHAR Datatypes that the SQL Server 2005 Driver offers up:
1 = uniqueidentifier : precision 36
1 = nchar : precision 4000
1 = char : precision 8000

Here is the order of the CHAR Datatypes that the SQL Server 2000 Driver offers up:
1 = char : precision 8000
1 = nchar : precision 4000
1 = uniqueidentifier : precision 36

When using the SQL Server 2005 Driver, I receive the following exception:
org.jpox.store.rdbms.mapping.CharRDBMSMapping, exception : String max length of 45 is outside the acceptable range [0, 36] for column "TRANSACTIONTYPE"

And this is because:
org.jpox.store.rdbms.mapping.CharRDBMSMapping
method: initialize()
.
   int maxlength = getTypeInfo().precision;
   column.checkString();
   if (column.getColumnMetaData().getLength().intValue() <= 0 || column.getColumnMetaData().getLength().intValue() > maxlength)
   {
      throw new JDOUserException("String max length of " + column.getColumnMetaData().getLength() + " is outside the acceptable range [0, " + maxlength + "] for column \"" + column.getIdentifier() + "\"");
   }
.
======================================================
column.getColumnMetaData().getLength().intValue() == 45
maxlength == 36
45 > 36 ---Exception is thrown
======================================================

I hope that this is enough information for you to reproduce the problem and hopefully fix the problem.

Also note, there are other Datatypes that could also be affected by the current JPOX code because they also have multiple variations that have different precisions.

For example:
-2 = binary : precision 8000
-2 = timestamp : precision 8
----
-1 = text : precision 2147483647
-1 = ntext : precision 1073741823
----
1 = char : precision 8000
1 = nchar : precision 4000
1 = uniqueidentifier : precision 36
----
3 = decimal : precision 38
3 = money : precision 19
3 = smallmoney : precision 10
3 = decimal() identity : precision 38
----
12 = varchar : precision 8000
12 = nvarchar : precision 4000
12 = sysname : precision 128
12 = sql_variant : precision 8000
----
93 = datetime : precision 23
93 = smalldatetime : precision 16


Let me know if you need anything else from me.

Thank you for your time.

-John Miller



 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Andy Jefferson - 11/Oct/06 05:16 PM
Hi,
I'm not commenting on code from 1.1.1. That is old. We provide nightly builds of latest code. Use that.
Please provide a testcase ... a proper one as per the Problem Reporting guide (which says very little about JUnit actually).

Andy Jefferson - 25/Oct/06 08:25 AM
Priority set to Minor until user provides a valid testcase

Andy Jefferson - 03/May/07 02:35 PM
Ok, after looking at the code (one of the few remaining parts of what was TJDO) I understand what you're saying. The simplest solution is to change the default so that the most common case is correct for all JDBC drivers. The more complete solution would be to load up ALL typeInfos and then use as appropriate to the RDBMSMapping and the particular column type in use.

Andy Jefferson - 03/May/07 04:28 PM
JPOX CVS HEAD now holds *all* database types for JDBC type provided by the MetaData and identifies the default database type to use. This currently follows the previous policy of taking the first record, but I've corrected the MSSQL case.

Andy Jefferson - 05/May/07 07:49 PM
In CVS HEAD and RELEASE_1_1. Confirmed by Pedram Abrari