Skip to content

Fix for the DerbyPlatform error SQLDataException:The syntax of the string representation of a date/time value is incorrect - #2649

Open
vavishal wants to merge 3 commits into
eclipse-ee4j:masterfrom
vavishal:derbyPlatformIssueFix
Open

vavishal wants to merge 3 commits into
eclipse-ee4j:masterfrom
vavishal:derbyPlatformIssueFix

Conversation

@vavishal

Copy link
Copy Markdown
Contributor

The org.eclipse.persistence.platform.database.DerbyPlatform#convertToDatabaseType method returns a java.sql.Date which doesn't include the time due to which some applications throws the following exception

java.sql.SQLDataException: The syntax of the string representation of a date/time value is incorrect.

So a fix has been done to return appropriate and correct values

Signed-off-by: Vaibhav Vishal vaibhav.vishal@oracle.com

@vavishal

vavishal commented Feb 18, 2026 •

Copy link
Copy Markdown
Contributor Author

Requesting @rfelcman to help review this change

@rfelcman

Copy link
Copy Markdown
Contributor

Please provide there some small test case or just definitions with data type used on DB side TIMESTAMP and entity side.

@vavishal vavishal changed the title Fir for derbyPlatformIssueFix Fix for derbyPlatformIssueFix Feb 23, 2026
@vavishal

vavishal commented Feb 23, 2026 •

Copy link
Copy Markdown
Contributor Author

Hi Radek (@rfelcman),

It is only seen for a soa application for which we cannot a unit testcase in eclipselink as I have tried several ways to try to reproduce it but unable to generate the following error
java.sql.SQLDataException: The syntax of the string representation of a date/time value is incorrect.

If you have some suggestions/pointers for it then I can try those too

@lukasj

lukasj commented Feb 27, 2026

Copy link
Copy Markdown
Member

While it may be difficult or impossible to share the test-case, it is easy to share the input/concrete value which gets passed to the method being changed - if that is a string, it is even better, if not, the type of that instance and some key attributes should be enough - ie debugger's copy value feature can help with this

@vavishal

vavishal commented Mar 3, 2026

Copy link
Copy Markdown
Contributor Author

The value object being passed to method org.eclipse.persistence.platform.database.DerbyPlatform#convertToDatabaseType method is of class "java.util.Date" and its value is "Mon Mar 02 05:54:19 UTC 2026"

After the call to Helper.sqlDateFromUtilDate((java.util.Date)value) the value object is of class "java.sql.Date" and its value is "2026-03-02"

@lukasj

lukasj commented Mar 6, 2026

Copy link
Copy Markdown
Member

and what is the column definition on the DB side? Is that a String, Timestamp, Date, Time or sth else?

@vavishal

vavishal commented Mar 11, 2026 •

Copy link
Copy Markdown
Contributor Author

The column definition on DB side is TIMESTAMP

@lukasj

lukasj commented Mar 11, 2026 •

Copy link
Copy Markdown
Member

Thank you. The very last question I have - isn't the bug in

} else if ((calendar.get(Calendar.HOUR_OF_DAY) == 0)
&& (calendar.get(Calendar.MINUTE) == 0)
&& (calendar.get(Calendar.SECOND) == 0)
&& (calendar.get(Calendar.MILLISECOND) == 0)) {
// PERF: If just a date set in the Calendar, then just use its millis.
return new java.sql.Date(calendar.getTimeInMillis());
}
return dateFromYearMonthDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE));
where the return values for the PERF and normal case are turned around?

@vavishal

Copy link
Copy Markdown
Contributor Author

I wrote a simple java code as follows to test it

import java.util.Date;
import org.eclipse.persistence.internal.helper.Helper;

public class sqlDate {
public static void main (String args[]) {
Date date = new Date();
Object value = Helper.sqlDateFromUtilDate(date);
System.out.println(value);
}
}

On running on the above code, it is getting returned by code at

return dateFromYearMonthDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE));
where we are seeing value as "2026-03-12"

After changing the code at line 1272 as follows

  •        return new java.sql.Date(calendar.getTimeInMillis());
    
  •    //return dateFromYearMonthDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE));
    

and then re-running the test yields the same result as before "2026-03-12"

@lukasj

lukasj commented Mar 12, 2026 •

Copy link
Copy Markdown
Member

and then re-running the test yields the same result as before "2026-03-12"

What have you done in order to understand why it is so and/or why the time part is not included in the output? Did you check the javadoc of java.sql.Date#toString()?

What happens if you update your test code to:

public class sqlDate {
    public static void main (String args[]) {
        Date utilDate = new Date();
        java.sql.Date sqlDate = Helper.sqlDateFromUtilDate(utilDate);
        System.out.println(utilDate);
        System.out.println(sqlDate);
        System.out.println(utilDate.getTime());
        System.out.println(sqlDate.getTime());
    }
}

Do you see any difference?

@vavishal

vavishal commented Mar 12, 2026 •

Copy link
Copy Markdown
Contributor Author

As per https://docs.oracle.com/en/java/javase/17/docs/api/java.sql/java/sql/Date.html#toString() it returns a String in yyyy-mm-dd format and it will not include any time part

Also as per javadoc https://docs.oracle.com/en/java/javase/17/docs/api/java.sql/java/sql/Date.html
To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated.

Are you saying calling the below code will return a java.sql.Date with time components set to 0

new java.sql.Date(calendar.getTimeInMillis())

But do you see any issue with the current change/fix done to org.eclipse.persistence.platform.database.DerbyPlatform#convertToDatabaseType method

I see similar code already existing for

@lukasj

lukasj commented Mar 12, 2026 •

Copy link
Copy Markdown
Member

well, I'd say that if the problem is in how exactly is particular data type formatted on the output side, then overriding

protected void appendDate(java.sql.Date date, Writer writer) throws IOException {
is probably better approach given that with the change you propose EclipseLink will likely call statement.setString(...). What is probaly prefered is thatstatement.setDate(..) gets called instead should the code get there. Does this make sense to you? This guessing without a reproducible test case is a bit challenging and time consuming :-/

@lukasj

lukasj commented Mar 12, 2026

Copy link
Copy Markdown
Member

or - another place to look at -

} else if (parameter.getClass() == CoreClassConstants.UTILDATE) {
statement.setTimestamp(index, Helper.timestampFromDate((java.util.Date) parameter));

...but I don't know which code path is your case taking

@lukasj

lukasj commented Mar 12, 2026

Copy link
Copy Markdown
Member

#2690 removes the method you want to update to fix test failure on Derby (ConversionManagerTestModelWithoutBinding fails, to run mvn -Ptest-lrg clean install; the change was introduced by #891) , check if that resolves the problem you're trying to fix with this change

@vavishal

vavishal commented Mar 13, 2026 •

Copy link
Copy Markdown
Contributor Author

On removing org.eclipse.persistence.platform.database.DerbyPlatform#convertToDatabaseType method I can see that following tests which was added by #891

org.eclipse.persistence.jpa.test.criteria.TestCoalesceFunction" name="testCoalesceFunction3Date"
is giving the following error

org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: The data type, length or value of arguments 'TIMESTAMP' and 'DATE' is incompatible.
Error Code: 30000
Call: SELECT t0.DESCRIPTION, COALESCE((SELECT t1.DATEVALUE FROM COALESCEENTITY t1), {ts '2026-03-13 04:43:02.771'}) FROM COALESCEENTITY t0
Query: ReportQuery(referenceClass=CoalesceEntity sql="SELECT t0.DESCRIPTION, COALESCE((SELECT t1.DATEVALUE FROM COALESCEENTITY t1), {ts '2026-03-13 04:43:02.771'}) FROM COALESCEENTITY t0")"

@lukasj

lukasj commented Mar 13, 2026

Copy link
Copy Markdown
Member

On removing org.eclipse.persistence.platform.database.DerbyPlatform#convertToDatabaseType method I can see that following tests which was added by #891

org.eclipse.persistence.jpa.test.criteria.TestCoalesceFunction" name="testCoalesceFunction3Date"

is giving the following error

org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLSyntaxErrorException: The data type, length or value of arguments 'TIMESTAMP' and 'DATE' is incompatible. Error Code: 30000 Call: SELECT t0.DESCRIPTION, COALESCE((SELECT t1.DATEVALUE FROM COALESCEENTITY t1), {ts '2026-03-13 04:43:02.771'}) FROM COALESCEENTITY t0 Query: ReportQuery(referenceClass=CoalesceEntity sql="SELECT t0.DESCRIPTION, COALESCE((SELECT t1.DATEVALUE FROM COALESCEENTITY t1), {ts '2026-03-13 04:43:02.771'}) FROM COALESCEENTITY t0")"

under which conditions? What do I have to do to reproduce this? On my end, mvn -U -C clean install -Poss-release -pl :org.eclipse.persistence.jpa.jse.test -Dit.test=TestCoalesceFunction passes

@vavishal

vavishal commented Mar 13, 2026 •

Copy link
Copy Markdown
Contributor Author

I don't have the derby setup for master branch but I am running it for 2.7.15 version

I have installed apache derby locally and then updated test.properties file as follows

jdbc.driver.jar=${extensions.depend.dir}/derby.jar:${extensions.depend.dir}/derbyclient.jar
db.driver=org.apache.derby.jdbc.ClientXADataSource
db.url=jdbc:derby:/tools/Apache/db-derby-10.15.2.0-bin/bin/MyDbTest
db.user=user
db.pwd=password
db.platform=org.eclipse.persistence.platform.database.DerbyPlatform

After which when I run the tests as follows then it errors out

ant -f antbuild.xml -Dtest.properties=/eclipselink/jpa/eclipselink.jpa.test.jse/test.properties test-jpa-jse

@vavishal

Copy link
Copy Markdown
Contributor Author

Are you able to reproduce the error in running the test org.eclipse.persistence.jpa.test.criteria.TestCoalesceFunction#testCoalesceFunction3Date after removing org.eclipse.persistence.platform.database.DerbyPlatform#convertToDatabaseType method

@lukasj

lukasj commented Mar 18, 2026 •

Copy link
Copy Markdown
Member

Yes. It is related to @Temporal(TemporalType.DATE) java.util.Date dateValue; field and eclipselink.jdbc.bind-parameters=false setting.

The code, which I removed, made that config working, but broke:

  • test in core
  • @Temporal(TemporalType.TIMESTAMP) java.util.Date dateValue;

therefore I believe current state - without the method being modified here - is better

the problem with this is also that it is unclear which case is this supposed to fix. In any case, the cause lies somewhere at runtime where the type conversion from java.util.Date to the type defined by the @Temporal is not happening and wrong type is passed to the DatabasePlatform implementation

@lukasj

lukasj commented Mar 18, 2026

Copy link
Copy Markdown
Member

basically following piece of code hidden in the mapping should be executed somewhere on the code path:

if (this.converter != null) {
    fieldValue = this.converter.convertObjectValueToDataValue(fieldValue, session);
}

before the fieldValue gets to the convertToDatabaseType

@vavishal

vavishal commented Apr 20, 2026 •

Copy link
Copy Markdown
Contributor Author

I checked further on this and the following code is not getting executed because converter is null

if (this.converter != null) {
fieldValue = this.converter.convertObjectValueToDataValue(fieldValue, session);
}

To get more info on this, I have added following debug statements

    System.out.println("[EL MAP PROBE] descriptor="
            + ((this.descriptor == null) ? "null" : this.descriptor.getJavaClassName()));
    System.out.println("[EL MAP PROBE] mappingClass=" + getClass().getName());
    System.out.println("[EL MAP PROBE] mappingAttribute=" + getAttributeName());
    System.out.println("[EL MAP PROBE] field=" + this.field);
    System.out.println("[EL MAP PROBE] fieldQualifiedName="
            + ((this.field == null) ? "null" : this.field.getQualifiedName()));
    System.out.println("[EL MAP PROBE] hasConverter=" + hasConverter());
    System.out.println("[EL MAP PROBE] converter="
            + ((this.converter == null) ? "null" : this.converter.getClass().getName()));
    System.out.println("[EL MAP PROBE] converterClassName="
            + ((this.converterClassName == null) ? "null" : this.converterClassName));
   System.out.println("[EL MAP PROBE] attributeClassification="
            + ((this.attributeClassification == null) ? "null" : this.attributeClassification.getName()));
    System.out.println("[EL MAP PROBE] attributeClassificationName="
            + ((this.attributeClassificationName == null) ? "null" : this.attributeClassificationName));
    System.out.println("[EL MAP PROBE] fieldClassificationClassName="
            + ((this.fieldClassificationClassName == null) ? "null" : this.fieldClassificationClassName));
    System.out.println("[EL MAP PROBE] fieldClassification=" + getFieldClassification());
    System.out.println("[EL MAP PROBE] fieldType(type)="
            + ((this.field == null) ? "null" : this.field.getType()));
    System.out.println("[EL MAP PROBE] fieldTypeName="
            + ((this.field == null) ? "null" : this.field.getTypeName()));
    System.out.println("[EL MAP PROBE] fieldSqlType="
            + ((this.field == null) ? "null" : this.field.getSqlType()));

and got the following outputs

[EL MAP PROBE] descriptor=oracle.soa.tracking.fabric.persistence.dao.FlowInstanceImpl
[EL MAP PROBE] mappingClass=org.eclipse.persistence.mappings.DirectToFieldMapping
[EL MAP PROBE] mappingAttribute=createdTime
[EL MAP PROBE] field=SCA_FLOW_INSTANCE.CREATED_TIME
[EL MAP PROBE] fieldQualifiedName=SCA_FLOW_INSTANCE.CREATED_TIME
[EL MAP PROBE] hasConverter=false
[EL MAP PROBE] converter=null
[EL MAP PROBE] converterClassName=null
[EL MAP PROBE] attributeClassification=java.util.Date
[EL MAP PROBE] attributeClassificationName=null
[EL MAP PROBE] fieldClassificationClassName=null
[EL MAP PROBE] fieldClassification=null
[EL MAP PROBE] fieldType(type)=null
[EL MAP PROBE] fieldTypeName=null
[EL MAP PROBE] fieldSqlType=-2147483648

@vavishal vavishal closed this Apr 22, 2026
@vavishal
vavishal force-pushed the derbyPlatformIssueFix branch from ee25887 to f3a30a8 Compare April 22, 2026 10:44
Signed-off-by: Vaibhav Vishal vaibhav.vishal@oracle.com
Signed-off-by: Vaibhav Vishal vaibhav.vishal@oracle.com
Signed-off-by: Vaibhav Vishal vaibhav.vishal@oracle.com
@vavishal vavishal changed the title Fix for derbyPlatformIssueFix Fix for SQLDataException:The syntax of the string representation of a date/time value is incorrect seen for DerbyPlatform Apr 23, 2026
@vavishal vavishal changed the title Fix for SQLDataException:The syntax of the string representation of a date/time value is incorrect seen for DerbyPlatform Fix for the DerbyPlatform error SQLDataException:The syntax of the string representation of a date/time value is incorrect Apr 23, 2026
@vavishal vavishal reopened this Apr 23, 2026
@vavishal

vavishal commented Apr 27, 2026 •

Copy link
Copy Markdown
Contributor Author

Requesting to help review it further

@vavishal

vavishal commented May 4, 2026 •

Copy link
Copy Markdown
Contributor Author

Waiting for the further review on this

@vavishal

vavishal commented Jun 4, 2026 •

Copy link
Copy Markdown
Contributor Author

Requesting to help review it further

@vavishal

Copy link
Copy Markdown
Contributor Author

Waiting for the further review on this
Requesting @lukaj to help review it further

@vavishal

vavishal commented Jun 23, 2026 •

Copy link
Copy Markdown
Contributor Author

Please help review this

@arjantijms arjantijms closed this Aug 22, 2026
@arjantijms arjantijms reopened this Aug 22, 2026
@arjantijms

Copy link
Copy Markdown
Contributor

Waiting for the further review on this Requesting @lukaj to help review it further

His username is @lukasj ;) lukaj is someone else.

@arjantijms

arjantijms commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

@robertpatrick one more to check, from our commiter candidate Vaibhav Vishal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants