persistence@glassfish.java.net

Issue 1454 and FieldDefinition.typeName?

From: Wonseok Kim <guruwons_at_gmail.com>
Date: Fri, 9 Mar 2007 22:04:56 +0900

Hi Tom,

I'm looking into issue 1454 columnDefinition="TEXT" does not apply in table
generation.
I'm fixing it, but I'm having problem in understanding the exact meaning of
typeName field in FieldDefinition class.

DatabaseField has 'columnDefinition' field corresponding to user-defined
column definition, and which is set to FieldDefinition's typeName(in this
case FieldDefinition's type is null).
But as you see below code, the typeName is used to set its 'type' field and
it is set to null!

TableDefinition.java
    /**
     * INTERNAL:
     * Build the field types based on the given name read in from the file.
     * Build the foriegn key constraints as well.
     */
    protected void buildFieldTypes(AbstractSession session) {
        buildForeignFieldTypes(session);
    }

    private void buildForeignFieldTypes(final AbstractSession session) {
        Hashtable fieldTypes = session.getPlatform().getClassTypes();
        FieldDefinition field = null;

        // The ForeignKeyConstraint object is the newer way of doing things.
        // We support FieldDefinition.getForeignKeyFieldName() due to
backwards compatibility
        // by converting it. To allow mixing both ways, we just add
converted one to foreignKeys list.

        for (Enumeration enumtr = getFields().elements();
enumtr.hasMoreElements();) {
            field = (FieldDefinition)enumtr.nextElement();
            if (field.getForeignKeyFieldName() != null) {
                addForeignKeyConstraint(buildForeignKeyConstraint(field,
session.getPlatform()));

            }
//FROM HERE - It's removing typeName(columnDefinition)!
            if (field.getType() == null) {
                field.setType((Class)fieldTypes.get(field.getTypeName()));
                if (field.getType() != null) {
                    field.setTypeName(null);
                }
            }
        }

    }

This does not keep user-defined column definition. I thought the code is
wrong and removed it. With some other changes, I could see the
user-specified column definition is used properly.
But, I found that the code is used for another purpose in
entity-persistence-tests. EPT is directly using FieldDefinition to generate
tables like below.

        FieldDefinition fieldSTREET = new FieldDefinition();
        fieldSTREET.setName("STREET");
        fieldSTREET.setTypeName("VARCHAR2");
        fieldSTREET.setSize(60);
        fieldSTREET.setSubSize(0);
        fieldSTREET.setIsPrimaryKey(false);
        fieldSTREET.setIsIdentity(false);
        fieldSTREET.setUnique(false);
        fieldSTREET.setShouldAllowNull(true);
        table.addField(fieldSTREET);

As you know typeName "VARCHAR2" is only for Oracle, so it could not be used
for other databases. The above type-related code is converting this
'typeName' to corresponding Java type which is converted to real database
type later according to DatabasePlatform.

What is the exact meaning of 'typeName'?
If it is type definition analogous to @Column.columnDefinition, then
tableCreators of EPT is abusing it - instead setType() should be used to be
portable.
If it should be translated according to DatabasePlatform, it should not be
used for @Column.columnDefinition.

Could you explain?

Thanks
-Wonseok