You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by "Heath Thomann (JIRA)" <ji...@apache.org> on 2010/01/08 18:50:54 UTC

[jira] Updated: (OPENJPA-1420) Long strings are improperly mapped on Informix

     [ https://issues.apache.org/jira/browse/OPENJPA-1420?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Heath Thomann updated OPENJPA-1420:
-----------------------------------

    Attachment: OPENJPA-1420.diff.txt

I've been working on a fix for this issue with assistance by Mike Dick.  I've provided a patch with the changes we propose.  Let me describe the changes and the rational behind the changes:

MappingInfo.java:
In method 'mergeColumn', the 'template Column' is merged with the 'given Column', where 'given' is what the user has specified in the @Column annotation.  Within the 'mergeColumn' method, the column's 'type' and 'size' are determine and set.  This is important because to fix this issue we need both the column type and size (i.e. when the column type is VARCHAR, and the size is greater than 255 we need to change the type).  This method is about the only place I could find where we know both 'type' and 'size' at the same time and can influence their values.  Ideally we want to keep the logic for this issue contained within InformixDictionary or at least DBDictionary.  However, neither class necessarily knows a columns type and size or has the opportunity to set the values.  As such, minor changes are needed in the 'mergeColumn' method to allow the InformixDictionary to influence the type and size.  To that end, we have moved the call to 'dict.getPreferredType' to a different spot AND we also overloaded this method.  'getPreferredType' already takes the 'type' as a parameter and returns the preferred type, as such this is a natural place to influence the type.  However, we also need the size in order to influence the type so we overloaded this method to take the 'size'.  'getPreferredType' is not defined on InformixDictionary as such the call is made on DBDictionary.  However, as you will see below, with my changes InformixDictionary overrides 'getPreferredType'.  

DBDictionary.java:
As was stated above, method 'getPreferredType' was overloaded to allow the 'size' to be passed as a parameter.  The existing 'getPreferredType' method, which takes only the 'type', delegates to the new 'getPreferredType' method, which takes the 'type' and 'size'.  Thus, if a subclass wants to influence the type based on the size, it can simple override this method. 

InformixDictionary.java:
First, in this class I added/override the new 'getPreferredType' method.  Within this method we can change the type of 'VARCHAR' to 'LONGVARCHAR' when the size is greater than 255.
Second, I noticed that in the method 'getColumns', there is logic to make a LONGVARCHAR a CLOB.  Given the changes proposed above, I do not think we want to always change a LONGVARCHAR to a CLOB.  As such, I created a new variable called 'useClobsForLongVarChar' which the user can set when they want the code to apply.

Finally, note that when the type is 'LONGVARCHAR', the longVarcharTypeName this maps to in InformixDictionary is this:
         longVarcharTypeName = "TEXT";

It was stated that LVARCHAR should be used, rather than TEXT.  However, for regression purposes, we'd like to leave the type name as TEXT, and allow the user to override it if necessary by setting the following property:
<propery name="openjpa.jdbc.DBDictionary" value="org.apache.openjpa.jdbc.sql.InformixDictionary(longVarcharTypeName=LVARCHAR)"/>

Thanks,

Heath

> Long strings are improperly mapped on Informix
> ----------------------------------------------
>
>                 Key: OPENJPA-1420
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-1420
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: jdbc
>    Affects Versions: 1.2.1
>         Environment: Windows XP 32-bit, Informix 11.5 database
>            Reporter: Marc Boudreau
>            Priority: Minor
>         Attachments: OPENJPA-1420.diff.txt
>
>
> The field:
> @Basic
> @Column(length=4000)
> private String description;
> gets mapped to VARCHAR(4000) which is illegal on Informix.  The limit for VARCHAR on Informix is 255.  The field should be mapped to LVARCHAR, which supports up to 32767 characters on Informix. TEXT  should only be used if the @Lob annotation is included, because this type can't be indexed.
> This is my test entity:
> MyEntity.java: 
> @Entity 
> public class MyEntity { 
>       @Id 
>       private int id; 
>       @Basic 
>       @Column(length=4000) 
>       private String description; 
>       public int getId() { 
>             return id; 
>       } 
>       public void setId(int value) { 
>             id = value; 
>       } 
>       public String getDescription() { 
>             return description; 
>       } 
>       public void setDescription(String value) { 
>             description = value; 
>       } 
> }
> This is what is dumped to the console:
> 2737  isvi  INFO   [main] openjpa.Runtime - Starting OpenJPA 1.2.1, 
> 2951  isvi  INFO   [main] openjpa.jdbc.JDBC - Using dictionary class 
> "org.apache.openjpa.jdbc.sql.InformixDictionary". 
> Exception in thread "main" <openjpa-1.2.1-r752877:753278 nonfatal general 
> error> org.apache.openjpa.persistence.PersistenceException: IDS SQL Error: 
> SQLCODE=-650, SQLSTATE=IX000, SQLERRMC=null, DRIVER=3.51.90 {stmnt 
> 809054265 CREATE TABLE MyEntity (id INTEGER NOT NULL, description VARCHAR 
> (4000), PRIMARY KEY (id)) LOCK MODE ROW} [code=-650, state=IX000] 
>       at org.apache.openjpa.jdbc.meta.MappingTool.record 
> (MappingTool.java:553) 
>       at org.apache.openjpa.jdbc.meta.MappingTool.record 
> (MappingTool.java:453) 
>       at 
> org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings 
> (JDBCBrokerFactory.java:159) 
>       at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.newBrokerImpl 
> (JDBCBrokerFactory.java:119) 
>       at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker 
> (AbstractBrokerFactory.java:189)) 
>       at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker 
> (DelegatingBrokerFactory.java:142) 
>       at 
> org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager 
> (EntityManagerFactoryImpl.java:192) 
>       at 
> org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager 
> (EntityManagerFactoryImpl.java:145) 
>       at 
> org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager 
> (EntityManagerFactoryImpl.java:56)) 
>       at jpa.test.isvi.Main.run(Main.java:12) 
>       at jpa.test.isvi.Main.main(Main.java:53) 
> Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: IDS SQL 
> Error: SQLCODE=-650, SQLSTATE=IX000, SQLERRMC=null, DRIVER=3.51.90 {stmnt 
> 809054265 CREATE TABLE MyEntity (id INTEGER NOT NULL, description VARCHAR 
> (4000), PRIMARY KEY (id)) LOCK MODE ROW} [code=-650, state=IX000] 
>       at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap 
> (LoggingConnectionDecorator.java:192) 
>       at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$700 
> (LoggingConnectionDecorator.java:57), 
>       at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator 
> $LoggingConnection$LoggingStatement.executeUpdate 
> (LoggingConnectionDecorator.java:762) 
>       at org.apache.openjpa.lib.jdbc.DelegatingStatement.executeUpdate 
> (DelegatingStatement.java:114) 
>       at org.apache.openjpa.jdbc.schema.SchemaTool.executeSQL 
> (SchemaTool.java:1191) 
>       at org.apache.openjpa.jdbc.schema.SchemaTool.createTable 
> (SchemaTool.java:949) 
>       at org.apache.openjpa.jdbc.schema.SchemaTool.add(SchemaTool.java:526) 
>       at org.apache.openjpa.jdbc.schema.SchemaTool.add(SchemaTool.java:344) 
>       at org.apache.openjpa.jdbc.schema.SchemaTool.run(SchemaTool.java:321) 
>       at org.apache.openjpa.jdbc.meta.MappingTool.record 
> (MappingTool.java:501): 
>       ... 10 more 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.