HHH-17355 Add array_to_string function
This commit is contained in:
parent
d558df9b64
commit
79e3af5464
|
@ -1138,6 +1138,7 @@ The following functions deal with SQL array types, which are not supported on ev
|
|||
| `array_replace()` | Creates array copy replacing a given element with another
|
||||
| `array_trim()` | Creates array copy trimming the last _N_ elements
|
||||
| `array_fill()` | Creates array filled with the same element _N_ times
|
||||
| `array_to_string()` | String representation of non-null array elements
|
||||
|===
|
||||
|
||||
===== `array()`
|
||||
|
@ -1429,6 +1430,19 @@ include::{array-example-dir-hql}/ArrayFillTest.java[tags=hql-array-fill-example]
|
|||
----
|
||||
====
|
||||
|
||||
===== `array_to_string()`
|
||||
|
||||
Concatenates the non-null array elements with a separator, as specified by the arguments.
|
||||
Returns `null` if the first argument is `null`.
|
||||
|
||||
[[hql-array-to-string-example]]
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{array-example-dir-hql}/ArrayToStringTest.java[tags=hql-array-to-string-example]
|
||||
----
|
||||
====
|
||||
|
||||
[[hql-user-defined-functions]]
|
||||
==== Native and user-defined functions
|
||||
|
||||
|
|
|
@ -479,6 +479,7 @@ public class CockroachLegacyDialect extends Dialect {
|
|||
functionFactory.arrayReplace();
|
||||
functionFactory.arrayTrim_trim_array();
|
||||
functionFactory.arrayFill_postgresql();
|
||||
functionFactory.arrayToString_postgresql();
|
||||
|
||||
functionContributions.getFunctionRegistry().register(
|
||||
"trunc",
|
||||
|
|
|
@ -388,6 +388,7 @@ public class H2LegacyDialect extends Dialect {
|
|||
functionFactory.arrayReplace_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayTrim_trim_array();
|
||||
functionFactory.arrayFill_h2();
|
||||
functionFactory.arrayToString_h2( getMaximumArraySize() );
|
||||
}
|
||||
else {
|
||||
// Use group_concat until 2.x as listagg was buggy
|
||||
|
|
|
@ -265,6 +265,7 @@ public class HSQLLegacyDialect extends Dialect {
|
|||
functionFactory.arrayReplace_unnest();
|
||||
functionFactory.arrayTrim_trim_array();
|
||||
functionFactory.arrayFill_hsql();
|
||||
functionFactory.arrayToString_hsql();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -301,6 +301,7 @@ public class OracleLegacyDialect extends Dialect {
|
|||
functionFactory.arrayReplace_oracle();
|
||||
functionFactory.arrayTrim_oracle();
|
||||
functionFactory.arrayFill_oracle();
|
||||
functionFactory.arrayToString_oracle();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -599,6 +599,7 @@ public class PostgreSQLLegacyDialect extends Dialect {
|
|||
functionFactory.arrayReplace();
|
||||
functionFactory.arrayTrim_trim_array();
|
||||
functionFactory.arrayFill_postgresql();
|
||||
functionFactory.arrayToString_postgresql();
|
||||
|
||||
if ( getVersion().isSameOrAfter( 9, 4 ) ) {
|
||||
functionFactory.makeDateTimeTimestamp();
|
||||
|
|
|
@ -466,6 +466,7 @@ public class CockroachDialect extends Dialect {
|
|||
functionFactory.arrayReplace();
|
||||
functionFactory.arrayTrim_trim_array();
|
||||
functionFactory.arrayFill_postgresql();
|
||||
functionFactory.arrayToString_postgresql();
|
||||
|
||||
functionContributions.getFunctionRegistry().register(
|
||||
"trunc",
|
||||
|
|
|
@ -327,6 +327,7 @@ public class H2Dialect extends Dialect {
|
|||
functionFactory.arrayReplace_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayTrim_trim_array();
|
||||
functionFactory.arrayFill_h2();
|
||||
functionFactory.arrayToString_h2( getMaximumArraySize() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -205,6 +205,7 @@ public class HSQLDialect extends Dialect {
|
|||
functionFactory.arrayReplace_unnest();
|
||||
functionFactory.arrayTrim_trim_array();
|
||||
functionFactory.arrayFill_hsql();
|
||||
functionFactory.arrayToString_hsql();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -541,6 +541,29 @@ public class OracleArrayJdbcType extends ArrayJdbcType {
|
|||
false
|
||||
)
|
||||
);
|
||||
database.addAuxiliaryDatabaseObject(
|
||||
new NamedAuxiliaryDatabaseObject(
|
||||
arrayTypeName + "_to_string",
|
||||
database.getDefaultNamespace(),
|
||||
new String[]{
|
||||
"create or replace function " + arrayTypeName + "_to_string(arr in " + arrayTypeName +
|
||||
", sep in varchar2) return varchar2 deterministic is " +
|
||||
"res varchar2(4000):=''; begin " +
|
||||
"if arr is null or sep is null then return null; end if; " +
|
||||
"for i in 1 .. arr.count loop " +
|
||||
"if arr(i) is not null then " +
|
||||
"if length(res)<>0 then res:=res||sep; end if; " +
|
||||
"res:=res||arr(i); " +
|
||||
"end if; " +
|
||||
"end loop; " +
|
||||
"return res; " +
|
||||
"end;"
|
||||
},
|
||||
new String[] { "drop function " + arrayTypeName + "_to_string" },
|
||||
emptySet(),
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected String createOrReplaceConcatFunction(String arrayTypeName) {
|
||||
|
|
|
@ -330,6 +330,7 @@ public class OracleDialect extends Dialect {
|
|||
functionFactory.arrayReplace_oracle();
|
||||
functionFactory.arrayTrim_oracle();
|
||||
functionFactory.arrayFill_oracle();
|
||||
functionFactory.arrayToString_oracle();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -647,6 +647,7 @@ public class PostgreSQLDialect extends Dialect {
|
|||
functionFactory.arrayReplace();
|
||||
functionFactory.arrayTrim_trim_array();
|
||||
functionFactory.arrayFill_postgresql();
|
||||
functionFactory.arrayToString_postgresql();
|
||||
|
||||
functionFactory.makeDateTimeTimestamp();
|
||||
// Note that PostgreSQL doesn't support the OVER clause for ordered set-aggregate functions
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.hibernate.dialect.function.array.ArrayRemoveIndexUnnestFunction;
|
|||
import org.hibernate.dialect.function.array.ArrayReplaceUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArraySetUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArraySliceUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayToStringFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayViaArgumentReturnTypeResolver;
|
||||
import org.hibernate.dialect.function.array.ElementViaArrayArgumentReturnTypeResolver;
|
||||
import org.hibernate.dialect.function.array.H2ArrayContainsFunction;
|
||||
|
@ -42,12 +43,14 @@ import org.hibernate.dialect.function.array.H2ArrayRemoveFunction;
|
|||
import org.hibernate.dialect.function.array.H2ArrayRemoveIndexFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArrayReplaceFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArraySetFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArrayToStringFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArrayConstructorFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArrayFillFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArrayPositionFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArrayPositionsFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArrayRemoveFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArraySetFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArrayToStringFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayConcatElementFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayConcatFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayFillFunction;
|
||||
|
@ -61,6 +64,7 @@ import org.hibernate.dialect.function.array.OracleArrayRemoveIndexFunction;
|
|||
import org.hibernate.dialect.function.array.OracleArrayReplaceFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArraySetFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArraySliceFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayToStringFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayTrimFunction;
|
||||
import org.hibernate.dialect.function.array.PostgreSQLArrayConcatElementFunction;
|
||||
import org.hibernate.dialect.function.array.PostgreSQLArrayConcatFunction;
|
||||
|
@ -3194,4 +3198,32 @@ public class CommonFunctionFactory {
|
|||
public void arrayFill_oracle() {
|
||||
functionRegistry.register( "array_fill", new OracleArrayFillFunction() );
|
||||
}
|
||||
|
||||
/**
|
||||
* H2 array_to_string() function
|
||||
*/
|
||||
public void arrayToString_h2(int maximumArraySize) {
|
||||
functionRegistry.register( "array_to_string", new H2ArrayToStringFunction( maximumArraySize, typeConfiguration ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* HSQL array_to_string() function
|
||||
*/
|
||||
public void arrayToString_hsql() {
|
||||
functionRegistry.register( "array_to_string", new HSQLArrayToStringFunction( typeConfiguration ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* CockroachDB and PostgreSQL array_to_string() function
|
||||
*/
|
||||
public void arrayToString_postgresql() {
|
||||
functionRegistry.register( "array_to_string", new ArrayToStringFunction( typeConfiguration ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Oracle array_to_string() function
|
||||
*/
|
||||
public void arrayToString_oracle() {
|
||||
functionRegistry.register( "array_to_string", new OracleArrayToStringFunction( typeConfiguration ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.dialect.function.array;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.ANY;
|
||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING;
|
||||
|
||||
/**
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
public class ArrayToStringFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
|
||||
public ArrayToStringFunction(TypeConfiguration typeConfiguration) {
|
||||
super(
|
||||
"array_to_string",
|
||||
FunctionKind.NORMAL,
|
||||
StandardArgumentsValidators.composite(
|
||||
new ArgumentTypesValidator( null, ANY, STRING ),
|
||||
ArrayArgumentValidator.DEFAULT_INSTANCE
|
||||
),
|
||||
StandardFunctionReturnTypeResolvers.invariant(
|
||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||
),
|
||||
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, ANY, STRING )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
sqlAppender.appendSql( "array_to_string(" );
|
||||
sqlAstArguments.get( 0 ).accept( walker );
|
||||
sqlAppender.appendSql( ',' );
|
||||
sqlAstArguments.get( 1 ).accept( walker );
|
||||
sqlAppender.appendSql( ')' );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.dialect.function.array;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* H2 requires a very special emulation, because {@code unnest} is pretty much useless,
|
||||
* due to https://github.com/h2database/h2database/issues/1815.
|
||||
* This emulation uses {@code array_get}, {@code array_length} and {@code system_range} functions to roughly achieve the same.
|
||||
*/
|
||||
public class H2ArrayToStringFunction extends ArrayToStringFunction {
|
||||
|
||||
private final int maximumArraySize;
|
||||
|
||||
public H2ArrayToStringFunction(int maximumArraySize, TypeConfiguration typeConfiguration) {
|
||||
super( typeConfiguration );
|
||||
this.maximumArraySize = maximumArraySize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression separatorExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
sqlAppender.append( "case when " );
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append( " is not null then coalesce((select listagg(array_get(" );
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append(",i.idx)," );
|
||||
separatorExpression.accept( walker );
|
||||
sqlAppender.append( ") within group (order by i.idx) from system_range(1,");
|
||||
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
||||
sqlAppender.append( ") i(idx) where i.idx<=coalesce(cardinality(");
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append("),0)),'') end" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.dialect.function.array;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* HSQLDB has a special syntax.
|
||||
*/
|
||||
public class HSQLArrayToStringFunction extends ArrayToStringFunction {
|
||||
|
||||
public HSQLArrayToStringFunction(TypeConfiguration typeConfiguration) {
|
||||
super( typeConfiguration );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression separatorExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
sqlAppender.append( "case when " );
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append( " is not null then coalesce((select group_concat(t.val order by t.idx separator " );
|
||||
// HSQLDB doesn't like non-literals as separator
|
||||
walker.render( separatorExpression, SqlAstNodeRenderingMode.INLINE_PARAMETERS );
|
||||
sqlAppender.append( ") from unnest(");
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append(") with ordinality t(val,idx)),'') end" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.dialect.function.array;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.ANY;
|
||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.INTEGER;
|
||||
|
||||
/**
|
||||
* Oracle array_to_string function.
|
||||
*/
|
||||
public class OracleArrayToStringFunction extends ArrayToStringFunction {
|
||||
|
||||
public OracleArrayToStringFunction(TypeConfiguration typeConfiguration) {
|
||||
super( typeConfiguration );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final String arrayTypeName = DdlTypeHelper.getTypeName(
|
||||
( (Expression) sqlAstArguments.get( 0 ) ).getExpressionType(),
|
||||
walker
|
||||
);
|
||||
sqlAppender.append( arrayTypeName );
|
||||
sqlAppender.append( "_to_string(" );
|
||||
sqlAstArguments.get( 0 ).accept( walker );
|
||||
sqlAppender.append( ',' );
|
||||
sqlAstArguments.get( 1 ).accept( walker );
|
||||
sqlAppender.append( ')' );
|
||||
}
|
||||
}
|
|
@ -15,7 +15,6 @@ import org.hibernate.boot.spi.InFlightMetadataCollector;
|
|||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.OracleArrayJdbcType;
|
||||
import org.hibernate.dialect.OracleDialect;
|
||||
import org.hibernate.dialect.SpannerDialect;
|
||||
import org.hibernate.engine.jdbc.Size;
|
||||
import org.hibernate.type.SqlTypes;
|
||||
|
@ -60,7 +59,6 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
|||
@SessionFactory
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsStructuralArrays.class)
|
||||
@SkipForDialect(dialectClass = SpannerDialect.class, reason = "Doesn't support array_agg ordering yet")
|
||||
@SkipForDialect(dialectClass = OracleDialect.class, majorVersion = 11, reason = "Oracle array_agg emulation requires json_arrayagg which was only added in Oracle 12")
|
||||
public class ArrayAggregateTest {
|
||||
|
||||
public static class UdtContributor implements AdditionalMappingContributor {
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.orm.test.function.array;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
/**
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
// Make sure this stuff runs on a dedicated connection pool,
|
||||
// otherwise we might run into ORA-21700: object does not exist or is marked for delete
|
||||
// because the JDBC connection or database session caches something that should have been invalidated
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.CONNECTION_PROVIDER, value = ""))
|
||||
@DomainModel(annotatedClasses = EntityWithArrays.class)
|
||||
@SessionFactory
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsStructuralArrays.class)
|
||||
public class ArrayToStringTest {
|
||||
|
||||
@BeforeEach
|
||||
public void prepareData(SessionFactoryScope scope) {
|
||||
scope.inTransaction( em -> {
|
||||
em.persist( new EntityWithArrays( 1L, new String[]{} ) );
|
||||
em.persist( new EntityWithArrays( 2L, new String[]{ "abc", null, "def" } ) );
|
||||
em.persist( new EntityWithArrays( 3L, null ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void cleanup(SessionFactoryScope scope) {
|
||||
scope.inTransaction( em -> {
|
||||
em.createMutationQuery( "delete from EntityWithArrays" ).executeUpdate();
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test(SessionFactoryScope scope) {
|
||||
scope.inSession( em -> {
|
||||
//tag::hql-array-to-string-example[]
|
||||
List<String> results = em.createQuery( "select array_to_string(e.theArray, ',') from EntityWithArrays e", String.class )
|
||||
.getResultList();
|
||||
//end::hql-array-to-string-example[]
|
||||
assertEquals( 3, results.size() );
|
||||
Assertions.assertThat( results.get( 0 ) ).isNullOrEmpty();
|
||||
assertEquals( "abc,def", results.get( 1 ) );
|
||||
assertNull( results.get( 2 ) );
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue