Support for SpEL inside @Query annotations.
Constructs like the following work now.
```
@Query("select u from User u where u.firstname = :#{#customer.firstname}")
List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);
```
Closes #619
Original pull request #229
See https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions
This commit is contained in:
committed by
Jens Schauder
parent
f326897950
commit
9abaa5a911
@@ -78,8 +78,10 @@ import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.ListCrudRepository;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.core.support.PropertiesBasedNamedQueries;
|
||||
import org.springframework.data.repository.query.ExtensionAwareQueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.FluentQuery;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.data.spel.spi.EvaluationContextExtension;
|
||||
import org.springframework.data.repository.query.QueryByExampleExecutor;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
@@ -90,6 +92,8 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.jdbc.JdbcTestUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Very simple use cases for creation and usage of JdbcRepositories.
|
||||
*
|
||||
@@ -97,6 +101,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
* @author Mark Paluch
|
||||
* @author Chirag Tailor
|
||||
* @author Diego Krupitza
|
||||
* @author Christopher Klein
|
||||
*/
|
||||
@Transactional
|
||||
@TestExecutionListeners(value = AssumeFeatureTestExecutionListener.class, mergeMode = MERGE_WITH_DEFAULTS)
|
||||
@@ -453,6 +458,17 @@ public class JdbcRepositoryIntegrationTests {
|
||||
assertThat(repository.countByName(one.getName())).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test // GH-619
|
||||
public void findBySpElWorksAsExpected() {
|
||||
DummyEntity r = repository.save(createDummyEntity());
|
||||
|
||||
// assign the new id to the global ID provider holder; this is similar to Spring Security's SecurityContextHolder
|
||||
MyIdContextProvider.ExtensionRoot.ID = r.getIdProp();
|
||||
|
||||
// expect, that we can find our newly created entity based upon the ID provider
|
||||
assertThat(repository.findWithSpEL().getIdProp()).isEqualTo(r.getIdProp());
|
||||
}
|
||||
|
||||
@Test // GH-945
|
||||
@EnabledOnFeature(TestDatabaseFeatures.Feature.IS_POSTGRES)
|
||||
public void usePrimitiveArrayAsArgument() {
|
||||
@@ -1305,6 +1321,9 @@ public class JdbcRepositoryIntegrationTests {
|
||||
|
||||
boolean existsByNameNotIn(String... names);
|
||||
|
||||
@Query("SELECT * FROM dummy_entity WHERE id_prop = :#{myext.id}")
|
||||
DummyEntity findWithSpEL();
|
||||
|
||||
boolean existsByName(String name);
|
||||
|
||||
int countByName(String name);
|
||||
@@ -1376,6 +1395,20 @@ public class JdbcRepositoryIntegrationTests {
|
||||
MyEventListener eventListener() {
|
||||
return new MyEventListener();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExtensionAwareQueryMethodEvaluationContextProvider extensionAware(List<EvaluationContextExtension> exts) {
|
||||
ExtensionAwareQueryMethodEvaluationContextProvider extensionAwareQueryMethodEvaluationContextProvider = new ExtensionAwareQueryMethodEvaluationContextProvider(exts);
|
||||
|
||||
factory.setEvaluationContextProvider(extensionAwareQueryMethodEvaluationContextProvider);
|
||||
|
||||
return extensionAwareQueryMethodEvaluationContextProvider;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EvaluationContextExtension evaluationContextExtension() {
|
||||
return new MyIdContextProvider();
|
||||
}
|
||||
}
|
||||
|
||||
interface RootRepository extends ListCrudRepository<Root, Long> {
|
||||
@@ -1417,6 +1450,27 @@ public class JdbcRepositoryIntegrationTests {
|
||||
}
|
||||
}
|
||||
|
||||
// DATAJDBC-397
|
||||
public static class MyIdContextProvider implements EvaluationContextExtension {
|
||||
@Override
|
||||
public String getExtensionId() {
|
||||
return "myext";
|
||||
}
|
||||
|
||||
public static class ExtensionRoot {
|
||||
// just public for testing purposes
|
||||
public static Long ID = 1L;
|
||||
|
||||
public Long getId() {
|
||||
return ID;
|
||||
}
|
||||
}
|
||||
|
||||
public Object getRootObject() {
|
||||
return new ExtensionRoot();
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
static class DummyEntity {
|
||||
|
||||
@@ -21,6 +21,7 @@ import static org.mockito.Mockito.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.JDBCType;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
@@ -49,6 +50,9 @@ import org.springframework.data.relational.core.sql.IdentifierProcessing;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.PropertiesBasedNamedQueries;
|
||||
import org.springframework.data.repository.query.ExtensionAwareQueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.spel.spi.EvaluationContextExtension;
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||
@@ -65,6 +69,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
* @author Mark Paluch
|
||||
* @author Dennis Effing
|
||||
* @author Chirag Tailor
|
||||
* @author Christopher Klein
|
||||
*/
|
||||
class StringBasedJdbcQueryUnitTests {
|
||||
|
||||
@@ -72,6 +77,7 @@ class StringBasedJdbcQueryUnitTests {
|
||||
NamedParameterJdbcOperations operations;
|
||||
RelationalMappingContext context;
|
||||
JdbcConverter converter;
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
@@ -80,6 +86,7 @@ class StringBasedJdbcQueryUnitTests {
|
||||
this.operations = mock(NamedParameterJdbcOperations.class);
|
||||
this.context = mock(RelationalMappingContext.class, RETURNS_DEEP_STUBS);
|
||||
this.converter = new BasicJdbcConverter(context, mock(RelationResolver.class));
|
||||
this.evaluationContextProvider = mock(QueryMethodEvaluationContextProvider.class);
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-165
|
||||
@@ -167,9 +174,10 @@ class StringBasedJdbcQueryUnitTests {
|
||||
|
||||
JdbcQueryMethod queryMethod = createMethod("sliceAll", Pageable.class);
|
||||
|
||||
assertThatThrownBy(() -> new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter))
|
||||
.isInstanceOf(UnsupportedOperationException.class)
|
||||
.hasMessageContaining("Slice queries are not supported using string-based queries");
|
||||
assertThatThrownBy(
|
||||
() -> new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter, evaluationContextProvider))
|
||||
.isInstanceOf(UnsupportedOperationException.class)
|
||||
.hasMessageContaining("Slice queries are not supported using string-based queries");
|
||||
}
|
||||
|
||||
@Test // GH-774
|
||||
@@ -177,17 +185,20 @@ class StringBasedJdbcQueryUnitTests {
|
||||
|
||||
JdbcQueryMethod queryMethod = createMethod("pageAll", Pageable.class);
|
||||
|
||||
assertThatThrownBy(() -> new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter))
|
||||
.isInstanceOf(UnsupportedOperationException.class)
|
||||
.hasMessageContaining("Page queries are not supported using string-based queries");
|
||||
assertThatThrownBy(
|
||||
() -> new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter, evaluationContextProvider))
|
||||
.isInstanceOf(UnsupportedOperationException.class)
|
||||
.hasMessageContaining("Page queries are not supported using string-based queries");
|
||||
}
|
||||
|
||||
@Test // GH-1212
|
||||
void convertsEnumCollectionParameterIntoStringCollectionParameter() {
|
||||
|
||||
JdbcQueryMethod queryMethod = createMethod("findByEnumTypeIn", Set.class);
|
||||
BasicJdbcConverter converter = new BasicJdbcConverter(mock(RelationalMappingContext.class), mock(RelationResolver.class));
|
||||
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, result -> mock(RowMapper.class), converter);
|
||||
BasicJdbcConverter converter = new BasicJdbcConverter(mock(RelationalMappingContext.class),
|
||||
mock(RelationResolver.class));
|
||||
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, result -> mock(RowMapper.class),
|
||||
converter, evaluationContextProvider);
|
||||
|
||||
query.execute(new Object[] { Set.of(Direction.LEFT, Direction.RIGHT) });
|
||||
|
||||
@@ -202,8 +213,12 @@ class StringBasedJdbcQueryUnitTests {
|
||||
void convertsEnumCollectionParameterUsingCustomConverterWhenRegisteredForType() {
|
||||
|
||||
JdbcQueryMethod queryMethod = createMethod("findByEnumTypeIn", Set.class);
|
||||
BasicJdbcConverter converter = new BasicJdbcConverter(mock(RelationalMappingContext.class), mock(RelationResolver.class), new JdbcCustomConversions(List.of(DirectionToIntegerConverter.INSTANCE, IntegerToDirectionConverter.INSTANCE)), JdbcTypeFactory.unsupported(), IdentifierProcessing.ANSI);
|
||||
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, result -> mock(RowMapper.class), converter);
|
||||
BasicJdbcConverter converter = new BasicJdbcConverter(mock(RelationalMappingContext.class),
|
||||
mock(RelationResolver.class),
|
||||
new JdbcCustomConversions(List.of(DirectionToIntegerConverter.INSTANCE, IntegerToDirectionConverter.INSTANCE)),
|
||||
JdbcTypeFactory.unsupported(), IdentifierProcessing.ANSI);
|
||||
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, result -> mock(RowMapper.class),
|
||||
converter, evaluationContextProvider);
|
||||
|
||||
query.execute(new Object[] { Set.of(Direction.LEFT, Direction.RIGHT) });
|
||||
|
||||
@@ -218,8 +233,10 @@ class StringBasedJdbcQueryUnitTests {
|
||||
void doesNotConvertNonCollectionParameter() {
|
||||
|
||||
JdbcQueryMethod queryMethod = createMethod("findBySimpleValue", Integer.class);
|
||||
BasicJdbcConverter converter = new BasicJdbcConverter(mock(RelationalMappingContext.class), mock(RelationResolver.class));
|
||||
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, result -> mock(RowMapper.class), converter);
|
||||
BasicJdbcConverter converter = new BasicJdbcConverter(mock(RelationalMappingContext.class),
|
||||
mock(RelationResolver.class));
|
||||
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, result -> mock(RowMapper.class),
|
||||
converter, evaluationContextProvider);
|
||||
|
||||
query.execute(new Object[] { 1 });
|
||||
|
||||
@@ -238,7 +255,7 @@ class StringBasedJdbcQueryUnitTests {
|
||||
}
|
||||
|
||||
private StringBasedJdbcQuery createQuery(JdbcQueryMethod queryMethod) {
|
||||
return new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter);
|
||||
return new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter, evaluationContextProvider);
|
||||
}
|
||||
|
||||
interface MyRepository extends Repository<Object, Long> {
|
||||
@@ -275,6 +292,35 @@ class StringBasedJdbcQueryUnitTests {
|
||||
|
||||
@Query(value = "some sql statement")
|
||||
List<Object> findBySimpleValue(Integer value);
|
||||
|
||||
@Query("SELECT * FROM table WHERE c = :#{myext.testValue} AND c2 = :#{myext.doSomething()}")
|
||||
Object findBySpelExpression(Object object);
|
||||
}
|
||||
|
||||
@Test // GH-619
|
||||
public void spelCanBeUsedInsideQueries() {
|
||||
|
||||
JdbcQueryMethod queryMethod = createMethod("findBySpelExpression", Object.class);
|
||||
|
||||
List<EvaluationContextExtension> list = new ArrayList<>();
|
||||
list.add(new MyEvaluationContextProvider());
|
||||
QueryMethodEvaluationContextProvider evaluationContextProviderImpl = new ExtensionAwareQueryMethodEvaluationContextProvider(
|
||||
list);
|
||||
|
||||
StringBasedJdbcQuery sut = new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter,
|
||||
evaluationContextProviderImpl);
|
||||
|
||||
ArgumentCaptor<SqlParameterSource> paramSource = ArgumentCaptor.forClass(SqlParameterSource.class);
|
||||
ArgumentCaptor<String> query = ArgumentCaptor.forClass(String.class);
|
||||
|
||||
sut.execute(new Object[] { "myValue" });
|
||||
|
||||
verify(this.operations).queryForObject(query.capture(), paramSource.capture(), any(RowMapper.class));
|
||||
|
||||
assertThat(query.getValue())
|
||||
.isEqualTo("SELECT * FROM table WHERE c = :__$synthetic$__1 AND c2 = :__$synthetic$__2");
|
||||
assertThat(paramSource.getValue().getValue("__$synthetic$__1")).isEqualTo("test-value1");
|
||||
assertThat(paramSource.getValue().getValue("__$synthetic$__2")).isEqualTo("test-value2");
|
||||
}
|
||||
|
||||
private static class CustomRowMapper implements RowMapper<Object> {
|
||||
@@ -307,7 +353,7 @@ class StringBasedJdbcQueryUnitTests {
|
||||
private enum Direction {
|
||||
LEFT, CENTER, RIGHT
|
||||
}
|
||||
|
||||
|
||||
@WritingConverter
|
||||
enum DirectionToIntegerConverter implements Converter<Direction, JdbcValue> {
|
||||
|
||||
@@ -354,4 +400,27 @@ class StringBasedJdbcQueryUnitTests {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
// DATAJDBC-397
|
||||
static class MyEvaluationContextProvider implements EvaluationContextExtension {
|
||||
@Override
|
||||
public String getExtensionId() {
|
||||
return "myext";
|
||||
}
|
||||
|
||||
public static class ExtensionRoot {
|
||||
public String getTestValue() {
|
||||
return "test-value1";
|
||||
}
|
||||
|
||||
public String doSomething() {
|
||||
return "test-value2";
|
||||
}
|
||||
}
|
||||
|
||||
public Object getRootObject() {
|
||||
return new ExtensionRoot();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.springframework.data.relational.core.mapping.RelationalMappingContext
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
@@ -58,6 +59,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
* @author Mark Paluch
|
||||
* @author Hebert Coelho
|
||||
* @author Diego Krupitza
|
||||
* @author Christopher Klein
|
||||
*/
|
||||
class JdbcQueryLookupStrategyUnitTests {
|
||||
|
||||
@@ -69,6 +71,7 @@ class JdbcQueryLookupStrategyUnitTests {
|
||||
private RepositoryMetadata metadata;
|
||||
private NamedQueries namedQueries = mock(NamedQueries.class);
|
||||
private NamedParameterJdbcOperations operations = mock(NamedParameterJdbcOperations.class);
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider = mock(QueryMethodEvaluationContextProvider.class);
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
@@ -127,12 +130,13 @@ class JdbcQueryLookupStrategyUnitTests {
|
||||
@ParameterizedTest
|
||||
@MethodSource("correctLookUpStrategyForKeySource")
|
||||
void correctLookUpStrategyForKey(QueryLookupStrategy.Key key, Class expectedClass) {
|
||||
|
||||
RowMapper<? extends NumberFormat> numberFormatMapper = mock(RowMapper.class);
|
||||
QueryMappingConfiguration mappingConfiguration = new DefaultQueryMappingConfiguration()
|
||||
.registerRowMapper(NumberFormat.class, numberFormatMapper);
|
||||
|
||||
QueryLookupStrategy queryLookupStrategy = JdbcQueryLookupStrategy.create(key, publisher, callbacks, mappingContext,
|
||||
converter, H2Dialect.INSTANCE, mappingConfiguration, operations, null);
|
||||
converter, H2Dialect.INSTANCE, mappingConfiguration, operations, null, evaluationContextProvider);
|
||||
|
||||
assertThat(queryLookupStrategy).isInstanceOf(expectedClass);
|
||||
}
|
||||
@@ -152,7 +156,7 @@ class JdbcQueryLookupStrategyUnitTests {
|
||||
QueryMappingConfiguration mappingConfiguration) {
|
||||
|
||||
QueryLookupStrategy queryLookupStrategy = JdbcQueryLookupStrategy.create(key, publisher, callbacks, mappingContext,
|
||||
converter, H2Dialect.INSTANCE, mappingConfiguration, operations, null);
|
||||
converter, H2Dialect.INSTANCE, mappingConfiguration, operations, null, evaluationContextProvider);
|
||||
|
||||
Method method = ReflectionUtils.findMethod(MyRepository.class, name);
|
||||
return queryLookupStrategy.resolveQuery(method, metadata, projectionFactory, namedQueries);
|
||||
|
||||
@@ -44,6 +44,8 @@ import org.springframework.data.relational.core.dialect.Dialect;
|
||||
import org.springframework.data.relational.core.mapping.NamingStrategy;
|
||||
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.query.ExtensionAwareQueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.spel.spi.EvaluationContextExtension;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
@@ -59,27 +61,36 @@ import org.springframework.transaction.PlatformTransactionManager;
|
||||
* @author Myeonghyeon Lee
|
||||
* @author Christoph Strobl
|
||||
* @author Chirag Tailor
|
||||
* @author Christopher Klein
|
||||
*/
|
||||
@Configuration
|
||||
@ComponentScan // To pick up configuration classes (per activated profile)
|
||||
public class TestConfiguration {
|
||||
|
||||
@Autowired DataSource dataSource;
|
||||
@Autowired BeanFactory beanFactory;
|
||||
@Autowired
|
||||
DataSource dataSource;
|
||||
@Autowired
|
||||
BeanFactory beanFactory;
|
||||
@Autowired ApplicationEventPublisher publisher;
|
||||
@Autowired(required = false) SqlSessionFactory sqlSessionFactory;
|
||||
@Autowired(required = false)
|
||||
SqlSessionFactory sqlSessionFactory;
|
||||
|
||||
@Bean
|
||||
JdbcRepositoryFactory jdbcRepositoryFactory(
|
||||
@Qualifier("defaultDataAccessStrategy") DataAccessStrategy dataAccessStrategy, RelationalMappingContext context,
|
||||
Dialect dialect, JdbcConverter converter, Optional<List<NamedQueries>> namedQueries) {
|
||||
@Qualifier("defaultDataAccessStrategy") DataAccessStrategy dataAccessStrategy,
|
||||
RelationalMappingContext context, Dialect dialect, JdbcConverter converter,
|
||||
Optional<List<NamedQueries>> namedQueries, List<EvaluationContextExtension> evaulationContextExtensions) {
|
||||
|
||||
JdbcRepositoryFactory factory = new JdbcRepositoryFactory(dataAccessStrategy, context, converter, dialect,
|
||||
publisher, namedParameterJdbcTemplate());
|
||||
namedQueries.map(it -> it.iterator().next()).ifPresent(factory::setNamedQueries);
|
||||
|
||||
factory.setEvaluationContextProvider(
|
||||
new ExtensionAwareQueryMethodEvaluationContextProvider(evaulationContextExtensions));
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
NamedParameterJdbcOperations namedParameterJdbcTemplate() {
|
||||
return new NamedParameterJdbcTemplate(dataSource);
|
||||
@@ -92,8 +103,8 @@ public class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
DataAccessStrategy defaultDataAccessStrategy(
|
||||
@Qualifier("namedParameterJdbcTemplate") NamedParameterJdbcOperations template, RelationalMappingContext context,
|
||||
JdbcConverter converter, Dialect dialect) {
|
||||
@Qualifier("namedParameterJdbcTemplate") NamedParameterJdbcOperations template,
|
||||
RelationalMappingContext context, JdbcConverter converter, Dialect dialect) {
|
||||
|
||||
return new DefaultDataAccessStrategy(new SqlGeneratorSource(context, converter, dialect), context, converter,
|
||||
template, new SqlParametersFactory(context, converter, dialect),
|
||||
@@ -128,8 +139,8 @@ public class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
JdbcConverter relationalConverter(RelationalMappingContext mappingContext, @Lazy RelationResolver relationResolver,
|
||||
CustomConversions conversions, @Qualifier("namedParameterJdbcTemplate") NamedParameterJdbcOperations template,
|
||||
Dialect dialect) {
|
||||
CustomConversions conversions,
|
||||
@Qualifier("namedParameterJdbcTemplate") NamedParameterJdbcOperations template, Dialect dialect) {
|
||||
|
||||
JdbcArrayColumns arrayColumns = dialect instanceof JdbcDialect ? ((JdbcDialect) dialect).getArraySupport()
|
||||
: JdbcArrayColumns.DefaultSupport.INSTANCE;
|
||||
|
||||
Reference in New Issue
Block a user