diff --git a/jmix-data/eclipselink/src/main/java/io/jmix/eclipselink/impl/dbms/JmixHSQLPlatform.java b/jmix-data/eclipselink/src/main/java/io/jmix/eclipselink/impl/dbms/JmixHSQLPlatform.java index fbc20a98bc..74f4791060 100644 --- a/jmix-data/eclipselink/src/main/java/io/jmix/eclipselink/impl/dbms/JmixHSQLPlatform.java +++ b/jmix-data/eclipselink/src/main/java/io/jmix/eclipselink/impl/dbms/JmixHSQLPlatform.java @@ -18,7 +18,9 @@ import org.eclipse.persistence.mappings.converters.Converter; import org.eclipse.persistence.platform.database.HSQLPlatform; +import org.eclipse.persistence.queries.Call; +import java.io.Writer; import java.sql.Types; public class JmixHSQLPlatform extends HSQLPlatform implements UuidMappingInfo { @@ -29,6 +31,11 @@ public boolean supportsNestingOuterJoins() { return true; } + @Override + public int appendParameterInternal(Call call, Writer writer, Object parameter) { + return super.appendParameterInternal(call, writer, convertToDataValueIfUUID(parameter)); + } + @Override public int getUuidSqlType() { return Types.VARCHAR; diff --git a/jmix-data/eclipselink/src/main/java/io/jmix/eclipselink/impl/dbms/JmixOraclePlatform.java b/jmix-data/eclipselink/src/main/java/io/jmix/eclipselink/impl/dbms/JmixOraclePlatform.java index e62aa41344..3f5579f7d3 100644 --- a/jmix-data/eclipselink/src/main/java/io/jmix/eclipselink/impl/dbms/JmixOraclePlatform.java +++ b/jmix-data/eclipselink/src/main/java/io/jmix/eclipselink/impl/dbms/JmixOraclePlatform.java @@ -17,9 +17,14 @@ package io.jmix.eclipselink.impl.dbms; import org.eclipse.persistence.exceptions.ConversionException; +import org.eclipse.persistence.internal.sessions.AbstractSession; import org.eclipse.persistence.mappings.converters.Converter; import org.eclipse.persistence.platform.database.Oracle10Platform; +import org.eclipse.persistence.queries.Call; +import java.io.Writer; +import java.sql.PreparedStatement; +import java.sql.SQLException; import java.sql.Types; import java.util.UUID; @@ -33,6 +38,16 @@ public Object convertObject(Object sourceObject, Class javaClass) throws Convers return super.convertObject(sourceObject, javaClass); } + @Override + public int appendParameterInternal(Call call, Writer writer, Object parameter) { + return super.appendParameterInternal(call, writer, convertToDataValueIfUUID(parameter)); + } + + @Override + public void setParameterValueInDatabaseCall(Object parameter, PreparedStatement statement, int index, AbstractSession session) throws SQLException { + super.setParameterValueInDatabaseCall(convertToDataValueIfUUID(parameter), statement, index, session); + } + @Override public int getUuidSqlType() { return Types.VARCHAR; diff --git a/jmix-data/eclipselink/src/main/java/io/jmix/eclipselink/impl/dbms/UuidMappingInfo.java b/jmix-data/eclipselink/src/main/java/io/jmix/eclipselink/impl/dbms/UuidMappingInfo.java index 68bb0aa0e0..f311ec8ab2 100644 --- a/jmix-data/eclipselink/src/main/java/io/jmix/eclipselink/impl/dbms/UuidMappingInfo.java +++ b/jmix-data/eclipselink/src/main/java/io/jmix/eclipselink/impl/dbms/UuidMappingInfo.java @@ -18,6 +18,8 @@ import org.eclipse.persistence.mappings.converters.Converter; +import java.util.UUID; + public interface UuidMappingInfo { int getUuidSqlType(); @@ -27,4 +29,22 @@ public interface UuidMappingInfo { String getUuidColumnDefinition(); Converter getUuidConverter(); + + /** + * Sometimes for some complex queries Eclipselink does not process collection parameter elements with converters. + * It only appends them to query using limited set of conversion checks instead. + * E.g. in org.eclipse.persistence.internal.databaseaccess.DatabasePlatform#setParameterValueInDatabaseCall(..) + * or in org.eclipse.persistence.internal.databaseaccess.DatabasePlatform#printValuelist(..) + * for case jmix-framework/jmix#1073 + *
+ * We have to convert UUID manually in such cases for several database types.
+ *
+ * @return converted to db type UUID parameter or the same parameter for other types
+ */
+ default Object convertToDataValueIfUUID(Object parameter) {
+ if (parameter instanceof UUID) {
+ parameter = getUuidConverter().convertObjectValueToDataValue(parameter, null);
+ }
+ return parameter;
+ }
}
diff --git a/jmix-data/eclipselink/src/test/groovy/jpa_converter/JpaConverterTest.groovy b/jmix-data/eclipselink/src/test/groovy/jpa_converter/JpaConverterTest.groovy
index d4c5e03953..6f94cf5026 100644
--- a/jmix-data/eclipselink/src/test/groovy/jpa_converter/JpaConverterTest.groovy
+++ b/jmix-data/eclipselink/src/test/groovy/jpa_converter/JpaConverterTest.groovy
@@ -18,11 +18,13 @@ package jpa_converter
import io.jmix.core.DataManager
import io.jmix.core.Id
+import org.springframework.beans.factory.annotation.Autowired
import test_support.DataSpec
+import test_support.entity.TestAppEntity
+import test_support.entity.TestAppEntityItem
import test_support.entity.TestConverterEntity
import test_support.entity.TestPhone
-import org.springframework.beans.factory.annotation.Autowired
import javax.sql.DataSource
class JpaConverterTest extends DataSpec {
@@ -55,4 +57,29 @@ class JpaConverterTest extends DataSpec {
def dataType = resultSet.getInt('DATA_TYPE')
dataType == java.sql.Types.VARCHAR
}
+
+ def "test UUID conversion for 'in' clause"() {
+ when:
+ def appEntity = dataManager.create(TestAppEntity)
+ appEntity.name = "test app entity 1"
+
+ def appEntityItem = dataManager.create(TestAppEntityItem)
+ appEntityItem.appEntity = appEntity
+
+ dataManager.save(appEntity, appEntityItem)
+
+ List