HHH-12202 Introduce ParameterType.getReturnedJavaType() as companion of getReturnedClass()
This commit is contained in:
parent
5c2fb290f5
commit
fa2e8f73e7
|
@ -26,6 +26,7 @@ import org.hibernate.Remove;
|
||||||
import org.hibernate.TimeZoneStorageStrategy;
|
import org.hibernate.TimeZoneStorageStrategy;
|
||||||
import org.hibernate.annotations.OnDeleteAction;
|
import org.hibernate.annotations.OnDeleteAction;
|
||||||
import org.hibernate.annotations.common.reflection.XProperty;
|
import org.hibernate.annotations.common.reflection.XProperty;
|
||||||
|
import org.hibernate.annotations.common.reflection.java.JavaXMember;
|
||||||
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
|
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
|
||||||
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
|
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
|
||||||
import org.hibernate.boot.model.convert.spi.JpaAttributeConverterCreationContext;
|
import org.hibernate.boot.model.convert.spi.JpaAttributeConverterCreationContext;
|
||||||
|
@ -71,6 +72,7 @@ import static org.hibernate.internal.util.collections.ArrayHelper.toBooleanArray
|
||||||
* A mapping model object that represents any value that maps to columns.
|
* A mapping model object that represents any value that maps to columns.
|
||||||
*
|
*
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
|
* @author Yanming Zhou
|
||||||
*/
|
*/
|
||||||
public abstract class SimpleValue implements KeyValue {
|
public abstract class SimpleValue implements KeyValue {
|
||||||
private static final CoreMessageLogger log = CoreLogging.messageLogger( SimpleValue.class );
|
private static final CoreMessageLogger log = CoreLogging.messageLogger( SimpleValue.class );
|
||||||
|
@ -943,6 +945,7 @@ public abstract class SimpleValue implements KeyValue {
|
||||||
classLoaderService.classForTypeName(
|
classLoaderService.classForTypeName(
|
||||||
typeParameters.getProperty(DynamicParameterizedType.RETURNED_CLASS)
|
typeParameters.getProperty(DynamicParameterizedType.RETURNED_CLASS)
|
||||||
),
|
),
|
||||||
|
xProperty instanceof JavaXMember ? ((JavaXMember) xProperty ).getJavaType() : null,
|
||||||
annotations,
|
annotations,
|
||||||
table.getCatalog(),
|
table.getCatalog(),
|
||||||
table.getSchema(),
|
table.getSchema(),
|
||||||
|
@ -985,6 +988,7 @@ public abstract class SimpleValue implements KeyValue {
|
||||||
|
|
||||||
return new ParameterTypeImpl(
|
return new ParameterTypeImpl(
|
||||||
classLoaderService.classForTypeName(typeParameters.getProperty(DynamicParameterizedType.RETURNED_CLASS)),
|
classLoaderService.classForTypeName(typeParameters.getProperty(DynamicParameterizedType.RETURNED_CLASS)),
|
||||||
|
xProperty instanceof JavaXMember ? ((JavaXMember) xProperty ).getJavaType() : null,
|
||||||
annotations,
|
annotations,
|
||||||
table.getCatalog(),
|
table.getCatalog(),
|
||||||
table.getSchema(),
|
table.getSchema(),
|
||||||
|
@ -1002,6 +1006,7 @@ public abstract class SimpleValue implements KeyValue {
|
||||||
private static final class ParameterTypeImpl implements DynamicParameterizedType.ParameterType {
|
private static final class ParameterTypeImpl implements DynamicParameterizedType.ParameterType {
|
||||||
|
|
||||||
private final Class<?> returnedClass;
|
private final Class<?> returnedClass;
|
||||||
|
private final java.lang.reflect.Type returnedJavaType;
|
||||||
private final Annotation[] annotationsMethod;
|
private final Annotation[] annotationsMethod;
|
||||||
private final String catalog;
|
private final String catalog;
|
||||||
private final String schema;
|
private final String schema;
|
||||||
|
@ -1012,6 +1017,7 @@ public abstract class SimpleValue implements KeyValue {
|
||||||
|
|
||||||
private ParameterTypeImpl(
|
private ParameterTypeImpl(
|
||||||
Class<?> returnedClass,
|
Class<?> returnedClass,
|
||||||
|
java.lang.reflect.Type returnedJavaType,
|
||||||
Annotation[] annotationsMethod,
|
Annotation[] annotationsMethod,
|
||||||
String catalog,
|
String catalog,
|
||||||
String schema,
|
String schema,
|
||||||
|
@ -1020,6 +1026,7 @@ public abstract class SimpleValue implements KeyValue {
|
||||||
String[] columns,
|
String[] columns,
|
||||||
Long[] columnLengths) {
|
Long[] columnLengths) {
|
||||||
this.returnedClass = returnedClass;
|
this.returnedClass = returnedClass;
|
||||||
|
this.returnedJavaType = returnedJavaType != null ? returnedJavaType : returnedClass;
|
||||||
this.annotationsMethod = annotationsMethod;
|
this.annotationsMethod = annotationsMethod;
|
||||||
this.catalog = catalog;
|
this.catalog = catalog;
|
||||||
this.schema = schema;
|
this.schema = schema;
|
||||||
|
@ -1034,6 +1041,11 @@ public abstract class SimpleValue implements KeyValue {
|
||||||
return returnedClass;
|
return returnedClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.lang.reflect.Type getReturnedJavaType() {
|
||||||
|
return returnedJavaType;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Annotation[] getAnnotationsMethod() {
|
public Annotation[] getAnnotationsMethod() {
|
||||||
return annotationsMethod;
|
return annotationsMethod;
|
||||||
|
|
|
@ -6,7 +6,10 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.usertype;
|
package org.hibernate.usertype;
|
||||||
|
|
||||||
|
import org.hibernate.Incubating;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +19,7 @@ import java.util.Properties;
|
||||||
* instead of the key {@value PARAMETER_TYPE}.
|
* instead of the key {@value PARAMETER_TYPE}.
|
||||||
*
|
*
|
||||||
* @author Janario Oliveira
|
* @author Janario Oliveira
|
||||||
|
* @author Yanming Zhou
|
||||||
*/
|
*/
|
||||||
public interface DynamicParameterizedType extends ParameterizedType {
|
public interface DynamicParameterizedType extends ParameterizedType {
|
||||||
String PARAMETER_TYPE = "org.hibernate.type.ParameterType";
|
String PARAMETER_TYPE = "org.hibernate.type.ParameterType";
|
||||||
|
@ -33,6 +37,11 @@ public interface DynamicParameterizedType extends ParameterizedType {
|
||||||
|
|
||||||
Class<?> getReturnedClass();
|
Class<?> getReturnedClass();
|
||||||
|
|
||||||
|
@Incubating
|
||||||
|
default Type getReturnedJavaType() {
|
||||||
|
return getReturnedClass();
|
||||||
|
}
|
||||||
|
|
||||||
Annotation[] getAnnotationsMethod();
|
Annotation[] getAnnotationsMethod();
|
||||||
|
|
||||||
String getCatalog();
|
String getCatalog();
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||||
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||||
import org.hibernate.metamodel.model.domain.BasicDomainType;
|
import org.hibernate.metamodel.model.domain.BasicDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.internal.BasicSqmPathSource;
|
import org.hibernate.metamodel.model.domain.internal.BasicSqmPathSource;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
|
@ -39,6 +40,8 @@ import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
import org.hibernate.type.CustomType;
|
import org.hibernate.type.CustomType;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
import org.hibernate.usertype.DynamicParameterizedType;
|
||||||
|
import org.hibernate.usertype.UserType;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -51,9 +54,10 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||||
* @author Daniel Gredler
|
* @author Daniel Gredler
|
||||||
* @author Jan-Willem Gmelig Meyling
|
* @author Jan-Willem Gmelig Meyling
|
||||||
* @author Sayra Ranjha
|
* @author Sayra Ranjha
|
||||||
|
* @author Yanming Zhou
|
||||||
*/
|
*/
|
||||||
@DomainModel(
|
@DomainModel(
|
||||||
annotatedClasses = { AbstractEntity.class, Entity1.class, Entity2.class }
|
annotatedClasses = { AbstractEntity.class, Entity1.class, Entity2.class, Entity3.class }
|
||||||
)
|
)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
@BootstrapServiceRegistry(
|
@BootstrapServiceRegistry(
|
||||||
|
@ -107,6 +111,22 @@ public class DynamicParameterizedTypeTest {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetReturnedJavaType(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(session -> {
|
||||||
|
EntityPersister persister = session.getEntityPersister("Entity3", new Entity3());
|
||||||
|
CustomType<?> mapping = (CustomType<?>) persister.findAttributeMapping("attributes").getSingleJdbcMapping();
|
||||||
|
UserType<?> userType = mapping.getUserType();
|
||||||
|
assertTrue(userType instanceof MyGenericType);
|
||||||
|
DynamicParameterizedType.ParameterType parameterType = ((MyGenericType) userType).getParameterType();
|
||||||
|
try {
|
||||||
|
assertEquals(parameterType.getReturnedJavaType(), Entity3.class.getDeclaredField("attributes").getGenericType());
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class FunctionContributorImpl implements FunctionContributor {
|
public static class FunctionContributorImpl implements FunctionContributor {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.annotations.type.dynamicparameterized;
|
||||||
|
|
||||||
|
import jakarta.persistence.Access;
|
||||||
|
import jakarta.persistence.AccessType;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import org.hibernate.annotations.Type;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Yanming Zhou
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Access(AccessType.FIELD)
|
||||||
|
public class Entity3 extends AbstractEntity {
|
||||||
|
|
||||||
|
@Type( MyGenericType.class )
|
||||||
|
Map<String, String> attributes;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.annotations.type.dynamicparameterized;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
import org.hibernate.usertype.DynamicParameterizedType;
|
||||||
|
import org.hibernate.usertype.UserType;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Yanming Zhou
|
||||||
|
*/
|
||||||
|
public class MyGenericType implements UserType<Object>, DynamicParameterizedType {
|
||||||
|
|
||||||
|
private ParameterType parameterType;
|
||||||
|
|
||||||
|
public ParameterType getParameterType() {
|
||||||
|
return parameterType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setParameterValues(Properties params) {
|
||||||
|
parameterType = (ParameterType) params.get(PARAMETER_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws SQLException {
|
||||||
|
st.setString( index, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSqlType() {
|
||||||
|
return Types.VARCHAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Object> returnedClass() {
|
||||||
|
return Object.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object x, Object y) {
|
||||||
|
return ( x == null && y == null ) || ( x != null && x.equals( y ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode(Object x) {
|
||||||
|
return x.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object deepCopy(Object value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMutable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable disassemble(Object value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String assemble(Serializable cached, Object owner) {
|
||||||
|
return (String) cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -42,6 +42,7 @@ import org.junit.Assert;
|
||||||
* makes it easier to verify that valid parameter values are being passed into {@link #setParameterValues(Properties)}.
|
* makes it easier to verify that valid parameter values are being passed into {@link #setParameterValues(Properties)}.
|
||||||
*
|
*
|
||||||
* @author Daniel Gredler
|
* @author Daniel Gredler
|
||||||
|
* @author Yanming Zhou
|
||||||
*/
|
*/
|
||||||
public class MyStringType implements UserType<String>, DynamicParameterizedType {
|
public class MyStringType implements UserType<String>, DynamicParameterizedType {
|
||||||
|
|
||||||
|
@ -85,6 +86,7 @@ public class MyStringType implements UserType<String>, DynamicParameterizedType
|
||||||
Assert.assertEquals( 1, parameterType.getColumns().length );
|
Assert.assertEquals( 1, parameterType.getColumns().length );
|
||||||
Assert.assertEquals( columnName, parameterType.getColumns()[0] );
|
Assert.assertEquals( columnName, parameterType.getColumns()[0] );
|
||||||
Assert.assertEquals( String.class, parameterType.getReturnedClass() );
|
Assert.assertEquals( String.class, parameterType.getReturnedClass() );
|
||||||
|
Assert.assertEquals( String.class, parameterType.getReturnedJavaType() );
|
||||||
Assert.assertEquals( tableName, parameterType.getTable() );
|
Assert.assertEquals( tableName, parameterType.getTable() );
|
||||||
|
|
||||||
String value = tableName + "." + columnName;
|
String value = tableName + "." + columnName;
|
||||||
|
@ -117,7 +119,7 @@ public class MyStringType implements UserType<String>, DynamicParameterizedType
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(String x, String y) {
|
public boolean equals(String x, String y) {
|
||||||
return ( x == null && y == null ) || ( x != null && y != null && x.equals( y ) );
|
return ( x == null && y == null ) || ( x != null && x.equals( y ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue