Skip to content

Commit

Permalink
HHH-17355 Support binding single element value for basic plural param…
Browse files Browse the repository at this point in the history
…eter types
  • Loading branch information
beikov committed Nov 7, 2023
1 parent eebb305 commit 6bbf589
Show file tree
Hide file tree
Showing 20 changed files with 124 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.hibernate.loader.ast.spi.MultiNaturalIdLoader;
import org.hibernate.loader.ast.spi.NaturalIdLoader;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingType;
Expand All @@ -43,7 +44,8 @@
/**
* Single-attribute NaturalIdMapping implementation
*/
public class SimpleNaturalIdMapping extends AbstractNaturalIdMapping implements JavaType.CoercionContext {
public class SimpleNaturalIdMapping extends AbstractNaturalIdMapping implements JavaType.CoercionContext,
BasicValuedMapping {
private final SingularAttributeMapping attribute;
private final SessionFactoryImplementor sessionFactory;
private final TypeConfiguration typeConfiguration;
Expand Down Expand Up @@ -241,6 +243,11 @@ public JdbcMapping getSingleJdbcMapping() {
return attribute.getSingleJdbcMapping();
}

@Override
public JdbcMapping getJdbcMapping() {
return attribute.getSingleJdbcMapping();
}

@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
return attribute.forEachJdbcType( offset, action );
Expand Down Expand Up @@ -317,4 +324,9 @@ public AttributeMapping asAttributeMapping() {
public boolean hasPartitionedSelectionMapping() {
return attribute.hasPartitionedSelectionMapping();
}

@Override
public MappingType getMappedType() {
return attribute.getMappedType();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import org.hibernate.query.BindableType;
import org.hibernate.query.QueryArgumentException;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.type.descriptor.java.BasicPluralJavaType;
import org.hibernate.type.descriptor.java.JavaType;

import jakarta.persistence.TemporalType;
Expand Down Expand Up @@ -142,13 +141,6 @@ else if ( temporalType != null ) {

return parameterDeclarationIsTemporal && bindIsTemporal;
}
// Allow binding a single element for a basic plural parameter type
else if ( expectedJavaType instanceof BasicPluralJavaType<?> ) {
final JavaType<?> elementJavaType = ( (BasicPluralJavaType<?>) expectedJavaType ).getElementJavaType();
if ( elementJavaType.isInstance( value ) ) {
return true;
}
}

return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
import org.hibernate.cache.MutableCacheKeyBuilder;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.IndexedConsumer;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.DiscriminatorType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
Expand All @@ -27,7 +29,7 @@
* @author Steve Ebersole
*/
public class EntityTypeLiteral
implements Expression, MappingModelExpressible<Object>, DomainResultProducer<Object>, JavaTypedExpressible<Object> {
implements Expression, DomainResultProducer<Object>, BasicValuedMapping {
private final EntityPersister entityTypeDescriptor;
private final DiscriminatorType<?> discriminatorType;

Expand All @@ -41,13 +43,23 @@ public EntityPersister getEntityTypeDescriptor() {
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// MappingModelExpressible
// BasicValuedMapping

@Override
public MappingModelExpressible getExpressionType() {
return this;
}

@Override
public JdbcMapping getJdbcMapping() {
return discriminatorType;
}

@Override
public MappingType getMappedType() {
return discriminatorType;
}

@Override
public int getJdbcTypeCount() {
return discriminatorType.getJdbcTypeCount();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
import org.hibernate.cache.MutableCacheKeyBuilder;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.IndexedConsumer;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.mapping.SqlExpressible;
import org.hibernate.metamodel.model.domain.internal.BasicTypeImpl;
import org.hibernate.query.BindableType;
Expand All @@ -38,7 +40,7 @@
* @author Steve Ebersole
*/
public abstract class AbstractJdbcParameter
implements JdbcParameter, JdbcParameterBinder, MappingModelExpressible, SqlExpressible {
implements JdbcParameter, JdbcParameterBinder, MappingModelExpressible, SqlExpressible, BasicValuedMapping {

private final JdbcMapping jdbcMapping;

Expand All @@ -56,6 +58,11 @@ public JdbcMapping getJdbcMapping() {
return jdbcMapping;
}

@Override
public MappingType getMappedType() {
return jdbcMapping;
}

@Override
public void accept(SqlAstWalker sqlTreeWalker) {
sqlTreeWalker.visitParameter( this );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.function.BiConsumer;

import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.Bindable;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.internal.BindingTypeHelper;
Expand Down Expand Up @@ -74,8 +75,15 @@ default int registerParametersForEachJdbcValue(
Bindable bindable,
JdbcParametersList jdbcParameters,
SharedSessionContractImplementor session) {
final Object valueToBind;
if ( bindable instanceof BasicValuedMapping ) {
valueToBind = ( (BasicValuedMapping) bindable ).getJdbcMapping().getMappedJavaType().wrap( value, session );
}
else {
valueToBind = value;
}
return bindable.forEachJdbcValue(
value,
valueToBind,
offset,
jdbcParameters,
session.getFactory().getTypeConfiguration(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
*/
package org.hibernate.type;

import java.lang.reflect.Array;
import java.util.Objects;

import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
Expand Down Expand Up @@ -56,20 +54,6 @@ public <X> BasicType<X> resolveIndicatedType(JdbcTypeIndicators indicators, Java
return (BasicType<X>) this;
}

@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
if ( value == null ) {
return null;
}
if ( baseDescriptor.isInstance( (E) value ) ) {
// Support binding a single element as parameter value
final Object array = Array.newInstance( baseDescriptor.getJavaType(), 1 );
Array.set( array, 0, value );
return array;
}
return value;
}

@Override
public boolean equals(Object o) {
return o == this || o.getClass() == BasicArrayType.class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
*/
package org.hibernate.type;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Objects;

import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.BasicCollectionJavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
Expand Down Expand Up @@ -77,21 +75,6 @@ public <X> BasicType<X> resolveIndicatedType(JdbcTypeIndicators indicators, Java
return (BasicType<X>) this;
}

@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
if ( value == null ) {
return null;
}
if ( baseDescriptor.isInstance( (E) value ) ) {
// Support binding a single element as parameter value
final BasicCollectionJavaType<C, E> javaType = (BasicCollectionJavaType<C, E>) getJavaTypeDescriptor();
final C collection = javaType.getSemantics().instantiateRaw( 1, null );
collection.add( (E) value );
return collection;
}
return value;
}

@Override
public boolean equals(Object o) {
return o == this || o.getClass() == BasicCollectionType.class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
*/
package org.hibernate.type;

import java.lang.reflect.Array;
import java.util.Objects;

import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
Expand Down Expand Up @@ -78,20 +76,6 @@ public <X> BasicType<X> resolveIndicatedType(JdbcTypeIndicators indicators, Java
return (BasicType<X>) this;
}

@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
if ( value == null ) {
return null;
}
if ( baseDescriptor.isInstance( (E) value ) ) {
// Support binding a single element as parameter value
final Object array = Array.newInstance( baseDescriptor.getJavaType(), 1 );
Array.set( array, 0, value );
return array;
}
return value;
}

@Override
public BasicValueConverter<T, ?> getValueConverter() {
return converter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,14 @@ else if ( value instanceof BinaryStream ) {
// When the value is a BinaryStream, this is a deserialization request
return fromBytes( ( (BinaryStream) value ).getBytes() );
}
else if ( getElementJavaType().isInstance( value ) ) {
// Support binding a single element as parameter value
//noinspection unchecked
final T[] wrapped = (T[]) java.lang.reflect.Array.newInstance( getElementJavaType().getJavaTypeClass(), 1 );
//noinspection unchecked
wrapped[0] = (T) value;
return wrapped;
}

throw unknownWrap( value.getClass() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ else if ( value.getClass().isArray() ) {
}
return wrapped;
}
else if ( value instanceof Boolean ) {
// Support binding a single element as parameter value
return new boolean[]{ (boolean) value };
}

throw unknownWrap( value.getClass() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ else if ( value.getClass().isArray() ) {
}
return wrapped;
}
else if ( value instanceof Double ) {
// Support binding a single element as parameter value
return new double[]{ (double) value };
}

throw unknownWrap( value.getClass() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ else if ( value.getClass().isArray() ) {
}
return wrapped;
}
else if ( value instanceof Float ) {
// Support binding a single element as parameter value
return new float[]{ (float) value };
}

throw unknownWrap( value.getClass() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ else if ( value.getClass().isArray() ) {
}
return wrapped;
}
else if ( value instanceof Integer ) {
// Support binding a single element as parameter value
return new int[]{ (int) value };
}

throw unknownWrap( value.getClass() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ else if ( value.getClass().isArray() ) {
}
return wrapped;
}
else if ( value instanceof Long ) {
// Support binding a single element as parameter value
return new long[]{ (long) value };
}

throw unknownWrap( value.getClass() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ public <X> byte[] wrap(X value, WrapperOptions options) {
throw new HibernateException( "Unable to access lob stream", e );
}
}
else if ( value instanceof Byte ) {
// Support binding a single element as parameter value
return new byte[]{ (byte) value };
}

throw unknownWrap( value.getClass() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ public <X> char[] wrap(X value, WrapperOptions options) {
if (value instanceof Reader) {
return DataHelper.extractString( ( (Reader) value ) ).toCharArray();
}
else if ( value instanceof Character ) {
// Support binding a single element as parameter value
return new char[]{ (char) value };
}
throw unknownWrap( value.getClass() );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ else if ( value.getClass().isArray() ) {
}
return wrapped;
}
else if ( value instanceof Short ) {
// Support binding a single element as parameter value
return new short[]{ (short) value };
}

throw unknownWrap( value.getClass() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,13 @@ else if ( value.getClass().isArray() ) {
}
return wrapped;
}
else if ( getElementJavaType().isInstance( value ) ) {
// Support binding a single element as parameter value
final C wrapped = semantics.instantiateRaw( 1, null );
//noinspection unchecked
wrapped.add( (E) value );
return wrapped;
}

throw unknownWrap( value.getClass() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,10 @@ public void testEmpty(SessionFactoryScope scope) {
@Test
public void testNonExisting(SessionFactoryScope scope) {
scope.inSession( em -> {
//tag::hql-array-example[]
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where e.theArray = array('abc')", EntityWithArrays.class )
.getResultList();
//end::hql-array-example[]
assertEquals( 0, results.size() );
} );
}
Expand Down

0 comments on commit 6bbf589

Please sign in to comment.