Skip to content

Commit

Permalink
Wrong SQL generated for IN operation and multi-tenancy add-on jmix-fr…
Browse files Browse the repository at this point in the history
  • Loading branch information
dtaimanov committed Dec 15, 2022
1 parent 3bd38d0 commit 25987bb
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import org.eclipse.persistence.mappings.converters.Converter;

import java.util.UUID;

public interface UuidMappingInfo {

int getUuidSqlType();
Expand All @@ -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
* <p>
* 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<TestAppEntityItem> items = dataManager.load(TestAppEntityItem)
.query("select i from test_TestAppEntityItem i where ((i.appEntity in :appEntities) and (('1' = '1') or (i.name = '1')))")
.parameter("appEntities", List.of(appEntity))
.list()
then:
noExceptionThrown()
items.size() == 1
items.iterator().next() == appEntityItem

cleanup:
if (appEntityItem != null) dataManager.remove(appEntityItem)
if (appEntity != null) dataManager.remove(appEntity)

}
}

0 comments on commit 25987bb

Please sign in to comment.