Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-dev] unique nullable="false" fields have no ' NOT NULL' in DDL

Hi Tom,

> Do you get "NOT NULL" on any of your database columns in any of your 
> table creation?

Yes, as you can see in the DDL I mentioned the other columns (SEQ and
CODE) do have "NOT NULL".

> The setting on FieldDefinition that set nullable comes from the setting 
> on DatabaseField.
> 
> Annotation processing that sets the nullable attribute for Directly 
> mapped fields occurs in the constructor for DirectColumnMetadata. That 
> information is put in the database field in the getDatabaseField() 
> method of that same class.
> 
> You should be able to find the other places where nullable is set by 
> searching for the setNullable(boolean) method on DatabaseField.

I have tracked the methods by adding Thread.dumpStack() methods in the
various methods, printing the classes' hashcode along with it.

I don't understand what's causing it, but this is what I am seeing:

When the DDL is generated correctly (recently in 70%  of cases),
MetaDataColumn#getDatabaseField creates a new DatabaseField for "UNQ1",
which is followed by an invocation of its setNullable method from
DirectColumnMataData's getDataBaseField method.
Later, from DefaultTableGenerator#getFieldDefFromDBField its
isNullable() method is called, which returns false as expected.

When the DDL is not generated correctly, the first part is the same as
above:
MetaDataColumn#getDatabaseField creates a new DatabaseField for "UNQ1",
which is followed by an invocation of its setNullable method from
DirectColumnMataData's getDataBaseField method. However, on this
instance, isNullable() is never called.
In the meantime, RelationalColumnMetadata#getPrimaryKeyField creates a
new DatabaseField for "UNQ1" again. On this instance setNullable is not
called.
Later, this is the instance DefaultTableGenerator#getFieldDefFromDBField
calls isNullable() on, which returns the incorrect value true.

Do you have any idea why it could be using the wrong instance from time
to time?

Thanks,
Dies


> Dies Koper wrote:
>> Hi Tom,
>>
>> I tried it again, and then it passed.
>> But then I tried again, and it failed.
>>
>> There must be some hashcode dependent or threading issue?
>>
>> I ran the following command 14 times in a row, 3 times it failed.
>>
>> D:\EclipseLink\jpa\eclipselink.jpa.test>ant 
>> -Dtest.class=org.eclipse.persistence.testing.tests.jpa.ddlgeneration.DDLGenerationJUni 
>>
>> tTestSuite test > test.txt
>>
>>> My Derby Config seems to be producing NOT NULL for me.
>>
>> Above was with Symfoware, and with all test methods but testSetup and 
>> testDDLUniqueKeysAsJoinColumns commented out.
>> I am trying now with JavaDB (GFv3's bundled one) but after 17 times so 
>> far it hasn't failed once...
>>
>>> A search in the code shows me "NOT NULL" is produced in one method.
>>> DatabasePlatform.printFieldNotNullClause(). 'Any chance you are
>>> overriding somewhere.
>>
>> No.
>>
>>> That method is called in FieldDefintion.appendDBString(Writer writer,
>>> AbstractSession session, TableDefinition table). Can you tell why you
>>> are not getting to that method call?
>>
>> In the following line in that method, both shouldAllowNull() methods 
>> return true, so it doesn't go into printFieldNotNullClause().
>>
>> if (shouldAllowNull() && fieldType.shouldAllowNull()) {
>>
>> I have not been able to find the path to look at in the debugger from 
>> where the annotation is read up to the point the shouldAllowNull 
>> variable should have been set to false.
>> Do you know where to look?
>>
>> Thanks,
>> Dies
>>
>>
>>> Dies Koper wrote:
>>>> Hi Tom,
>>>>
>>>> I checked with Derby, no 'NOT NULL' either, so it's not just Symfoware.
>>>> But when I checked my old logs (from September 2009), it did have it.
>>>> Something must have changed since.
>>>>
>>>> I also just tried with Oracle, 'NOT NULL' is there.
>>>>
>>>> I noticed that when I comment out the following line in
>>>> jpa\eclipselink.jpa.test\resource\eclipselink-ddl-generation-model\persistence.xml, 
>>>>
>>>> the 'NOT NULL' indication reappears for Derby.
>>>>
>>>>
>>>> <class>org.eclipse.persistence.testing.models.jpa.ddlgeneration.PropertyInfo</class> 
>>>>
>>>>
>>>>
>>>> I've looked at this issue in the debugger for several hours but I have
>>>> no idea what's going on. Any ideas?
>>>>
>>>> Thanks,
>>>> Dies
>>>>
>>>>
>>>> On 26/01/2010 08:27, Tom Ware wrote:
>>>>> Hi Dies,
>>>>>
>>>>> Here is the SQL I get when I run on MySQL.
>>>>>
>>>>> CREATE TABLE DDL_CKENTB (DTYPE VARCHAR2(31) NULL, UNQ1 
>>>>> VARCHAR2(255) NOT
>>>>> NULL, UNQ2 VARCHAR2(255) NOT NULL, SEQ NUMBER(19) NOT NULL, CODE
>>>>> VARCHAR2(255) NOT NULL, PRIMARY KEY (SEQ, CODE))
>>>>>
>>>>> It seems to have the NOT NULL indications.
>>>>>
>>>>> -Tom
>>>>>
>>>>> Dies Koper wrote:
>>>>>> Hi,
>>>>>>
>>>>>> I was wondering whether anyone noticed this already:
>>>>>>
>>>>>> JPA LRG's JPtestDDLUniqueKeysAsJoinColumns fails on Symfoware because
>>>>>> the table could not be created.
>>>>>> The database complains that I'm defining a unique constraint on 
>>>>>> columns
>>>>>> that are nullable. This is CREATE statement:
>>>>>>
>>>>>> CREATE TABLE DDL_CKENTB
>>>>>> (DTYPE VARCHAR(31),
>>>>>> UNQ1 VARCHAR(255),
>>>>>> UNQ2 VARCHAR(255),
>>>>>> SEQ NUMERIC(18) NOT NULL,
>>>>>> CODE VARCHAR(255) NOT NULL,
>>>>>> PRIMARY KEY (SEQ, CODE),
>>>>>> UNIQUE (UNQ2, UNQ1))
>>>>>>
>>>>>> But the entity (CKeyEntityB) has them defined as non-nullable, it 
>>>>>> seems
>>>>>> that is ignored.
>>>>>>
>>>>>> @Column(name = "UNQ1", nullable = false)
>>>>>> private String unq1;
>>>>>> @Column(name = "UNQ2", nullable = false)
>>>>>> private String unq2;
>>>>>>
>>>>>> Thanks,
>>>>>> Dies



Back to the top