Skip to content

Commit

Permalink
Introduce VirtualIdEmbeddable and IdClassEmbeddable
Browse files Browse the repository at this point in the history
EmbeddableInstantiator

Still need to
  - integrate EmbeddableInstantiator work
  - integrate embedded forms.  `VirtualIdEmbeddable` does not really need it as it can use the id-mapping itself as the embedded form.  But `IdClassEmbedded` should really be integrated
  - integrate `VirtualKeyEmbeddable` and `VirtualKeyEmbedded` for use as inverse composite fks
  - share `#finishInit` handling for `EmbeddableMappingType`, `VirtualIdEmbeddable` and `IdClassEmbeddable`
  • Loading branch information
sebersole committed Dec 1, 2021
1 parent 546a635 commit 0322d8f
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,64 +8,45 @@

/**
* Represents reflection optimization for a particular class.
*
* @author Steve Ebersole
*/
public interface ReflectionOptimizer {
/**
* Retrieve the optimizer for calling an entity's constructor via reflection.
*
* @return The optimizer for instantiation
*/
public InstantiationOptimizer getInstantiationOptimizer();
InstantiationOptimizer getInstantiationOptimizer();

/**
* Retrieve the optimizer for accessing the entity's persistent state.
*
* @return The optimizer for persistent state access
*/
public AccessOptimizer getAccessOptimizer();
AccessOptimizer getAccessOptimizer();

/**
* Represents optimized entity instantiation.
*/
public static interface InstantiationOptimizer {
interface InstantiationOptimizer {
/**
* Perform instantiation of an instance of the underlying class.
*
* @return The new instance.
*/
public Object newInstance();
Object newInstance();
}

/**
* Represents optimized entity property access.
*
* @author Steve Ebersole
*/
public interface AccessOptimizer {
interface AccessOptimizer {
/**
* Get the name of all properties.
*
* @return The name of all properties.
*/
public String[] getPropertyNames();
String[] getPropertyNames();

/**
* Get the value of all properties from the given entity
*
* @param object The entity from which to extract values.
*
* @return The values.
*/
public Object[] getPropertyValues(Object object);
Object[] getPropertyValues(Object object);

/**
* Set all property values into an entity instance.
*
* @param object The entity instance
* @param values The values to inject
*/
public void setPropertyValues(Object object, Object[] values);
void setPropertyValues(Object object, Object[] values);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@
package org.hibernate.loader;

import org.hibernate.internal.util.StringHelper;
import org.hibernate.query.NavigablePath;

/**
* @author Steve Ebersole
*/
public class PropertyPath {
public static final String IDENTIFIER_MAPPER_PROPERTY = "_identifierMapper";
public static final String IDENTIFIER_MAPPER_PROPERTY = NavigablePath.IDENTIFIER_MAPPER_PROPERTY;


private final PropertyPath parent;
private final String property;
private final String fullPath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.function.Supplier;

import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
import org.hibernate.type.descriptor.java.JavaType;

Expand All @@ -17,21 +18,25 @@
/**
* Support for instantiating embeddables as POJO representation
* using bytecode optimizer
*
* @author Steve Ebersole
*/
public class EmbeddableInstantiatorPojoOptimized extends AbstractPojoInstantiator implements EmbeddableInstantiator {
private final Supplier<EmbeddableMappingType> embeddableMappingAccess;
private final InstantiationOptimizer instantiationOptimizer;

public EmbeddableInstantiatorPojoOptimized(
JavaType<?> javaTypeDescriptor,
Supplier<EmbeddableMappingType> embeddableMappingAccess,
InstantiationOptimizer instantiationOptimizer) {
super( javaTypeDescriptor.getJavaTypeClass() );
this.embeddableMappingAccess = embeddableMappingAccess;
this.instantiationOptimizer = instantiationOptimizer;
}

@Override
public Object instantiate(Supplier<Object[]> valuesAccess, SessionFactoryImplementor sessionFactory) {
return instantiationOptimizer.newInstance();
final Object embeddable = instantiationOptimizer.newInstance();
final EmbeddableMappingType embeddableMapping = embeddableMappingAccess.get();
embeddableMapping.setPropertyValues( embeddable, valuesAccess.get() );
return embeddable;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import java.util.function.Supplier;

import org.hibernate.InstantiationException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreLogging;
Expand All @@ -22,18 +21,15 @@

/**
* Support for instantiating embeddables as POJO representation
*
* @author Steve Ebersole
*/
public class EmbeddableInstantiatorPojoStandard extends AbstractPojoInstantiator implements EmbeddableInstantiator {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( PojoInstantiatorImpl.class );

private final Supplier<EmbeddableMappingType> embeddableMappingAccess;
private final boolean constructorInjection = false;
private final Constructor<?> constructor;

public EmbeddableInstantiatorPojoStandard(
Supplier<EmbeddableMappingType> embeddableMappingAccess,
JavaType<?> javaTypeDescriptor) {
public EmbeddableInstantiatorPojoStandard(JavaType<?> javaTypeDescriptor, Supplier<EmbeddableMappingType> embeddableMappingAccess) {
super( javaTypeDescriptor.getJavaTypeClass() );

this.embeddableMappingAccess = embeddableMappingAccess;
Expand All @@ -54,29 +50,29 @@ protected static Constructor<?> resolveConstructor(Class<?> mappedPojoClass) {
@Override
public Object instantiate(Supplier<Object[]> valuesAccess, SessionFactoryImplementor sessionFactory) {
if ( isAbstract() ) {
throw new InstantiationException( "Cannot instantiate abstract class or interface: ", getMappedPojoClass() );
throw new InstantiationException(
"Cannot instantiate abstract class or interface: ", getMappedPojoClass()
);
}

if ( constructor == null ) {
throw new InstantiationException( "No default constructor for embeddable: ", getMappedPojoClass() );
throw new InstantiationException( "Unable to locate constructor for embeddable", getMappedPojoClass() );
}

if ( valuesAccess != null ) {
if ( constructor.getParameterTypes().length > 0 ) {
// constructor injection
throw new NotYetImplementedFor6Exception( "Constructor injection for embeddables not yet implemented" );
try {
if ( constructorInjection ) {
return constructor.newInstance( valuesAccess.get() );
}
}

try {
final Object instance = constructor.newInstance();
if ( valuesAccess != null ) {
embeddableMappingAccess.get().setPropertyValues( instance, valuesAccess.get() );
}

return instance;
}
catch ( Exception e ) {
throw new InstantiationException( "Could not instantiate embeddable: ", getMappedPojoClass(), e );
throw new InstantiationException( "Could not instantiate entity: ", getMappedPojoClass(), e );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,12 @@ private EmbeddableInstantiator determineInstantiator(Supplier<EmbeddableMappingT
final ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer = reflectionOptimizer.getInstantiationOptimizer();
return new EmbeddableInstantiatorPojoOptimized(
getEmbeddableJavaTypeDescriptor(),
runtimeDescriptorAccess,
instantiationOptimizer
);
}

return new EmbeddableInstantiatorPojoStandard(
runtimeDescriptorAccess,
getEmbeddableJavaTypeDescriptor()
);
return new EmbeddableInstantiatorPojoStandard( getEmbeddableJavaTypeDescriptor(), runtimeDescriptorAccess );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@
import org.hibernate.metamodel.mapping.MappingModelCreationLogger;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping;
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping.IdentifierValueMapper;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.SelectableConsumer;
import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.mapping.SelectableMappings;
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping.IdentifierValueMapper;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
import org.hibernate.persister.entity.EntityPersister;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
import org.hibernate.type.descriptor.java.JavaType;

/**
* @author Steve Ebersole
* EmbeddableRepresentationStrategy for an IdClass mapping
*/
public class IdClassRepresentationStrategy implements EmbeddableRepresentationStrategy {
private final JavaType<?> idClassType;
private final EmbeddableInstantiator instantiator;

public IdClassRepresentationStrategy(IdClassEmbeddable idClassEmbeddable) {
this.idClassType = idClassEmbeddable.getMappedJavaTypeDescriptor();
this.instantiator = new EmbeddableInstantiatorPojoStandard( () -> idClassEmbeddable, idClassType );
this.instantiator = new EmbeddableInstantiatorPojoStandard( idClassType, () -> idClassEmbeddable );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
import org.hibernate.mapping.RootClass;
import org.hibernate.metamodel.internal.AbstractCompositeIdentifierMapping;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import org.hibernate.query.DotIdentifierSequence;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.query.NavigablePath;

/**
* Poorly named.
Expand All @@ -21,7 +22,7 @@
* @author Steve Ebersole
*/
public class NavigableRole implements DotIdentifierSequence {
public static final String IDENTIFIER_MAPPER_PROPERTY = "_identifierMapper";
public static final String IDENTIFIER_MAPPER_PROPERTY = NavigablePath.IDENTIFIER_MAPPER_PROPERTY;

private final NavigableRole parent;
private final String localName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@
*/
package org.hibernate.metamodel.spi;

import java.util.function.IntFunction;
import java.util.function.Supplier;

import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.spi.SessionFactoryImplementor;

/**
* Contract for instantiating embeddable values
*
* @author Steve Ebersole
*/
public interface EmbeddableInstantiator extends Instantiator {
/**
* Create an instance of the embeddable
*/
Object instantiate(Supplier<Object[]> valuesAccess, SessionFactoryImplementor sessionFactory);

// default Object instantiate(IntFunction<Object> valueAccess, SessionFactoryImplementor sessionFactory) {
// throw new NotYetImplementedFor6Exception( getClass() );
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,7 @@ protected void notifyParentResolutionListeners(Object parentInstance) {
for ( Consumer<Object> listener : listeners ) {
listener.accept( parentInstance );
}

listeners.clear();
}
}

0 comments on commit 0322d8f

Please sign in to comment.