All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.metamodel.model.domain.spi.EntityIdentifier Maven / Gradle / Ivy

There is a newer version: 7.0.0.Alpha3
Show newest version
/*
 * 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.metamodel.model.domain.spi;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.metamodel.model.relational.spi.Column;
import org.hibernate.sql.ast.produce.spi.ColumnReferenceQualifier;
import org.hibernate.sql.ast.produce.spi.SqlAstCreationContext;
import org.hibernate.sql.ast.produce.spi.SqlSelectionExpression;
import org.hibernate.sql.ast.tree.spi.expression.ColumnReference;
import org.hibernate.sql.ast.tree.spi.expression.Expression;
import org.hibernate.sql.exec.spi.ExecutionContext;

/**
 * Descriptor for an entity's identifier
 *
 * @todo (6.0) : drop SingularPersistentAttribute from extends list
 * 		only 2 out of the 3 identifier forms is a SingularPersistentAttribute, the 3rd is the
 * 		"non-aggregated cid" form.  Granted we could model the 3rd as a
 * 		{@link VirtualPersistentAttribute} (or a {@link VirtualNavigable}) but the underlying issue
 * 		is the abstract base class ({@link AbstractSingularPersistentAttribute}) and what we can pass
 * 		to its ctor - ideally we'd pass the boot-model form
 * 		({@link org.hibernate.boot.model.domain.PersistentAttributeMapping}) which does not exist
 * 		for this 3rd id form.
 *
 * @author Steve Ebersole
 */
public interface EntityIdentifier extends Navigable, AllowableOutputParameterType {
	String NAVIGABLE_ID = "{id}";
	String LEGACY_NAVIGABLE_ID = "id";

	@Override
	SimpleTypeDescriptor getNavigableType();

	/**
	 * Is this identifier defined by a single attribute on the entity?
	 * 

* The only time this is false is in the case of a non-aggregated composite identifier. * * @return {@code false} indicates we have a non-aggregated composite identifier. */ default boolean hasSingleIdAttribute() { return this instanceof SingularPersistentAttribute; } @SuppressWarnings("unchecked") default J extractIdentifier(E entityInstance, SharedSessionContractImplementor session) { // todo (6.0) : EntityIdentifierCompositeNonAggregated is not a PersistentAttribute return (J) asAttribute( getJavaType() ).getPropertyAccess().getGetter().get( entityInstance ); } default void injectIdentifier(J entity, J id, SharedSessionContractImplementor session) { asAttribute( getJavaType() ).getPropertyAccess().getSetter().set( entity, id, session.getFactory() ); } /** * Get a SingularPersistentAttribute representation of the identifier. *

* Note that for the case of a non-aggregated composite identifier this returns a * "virtual" attribute mapping ({@link VirtualPersistentAttribute}) * * @todo (6.0) : decide on what we want to do here. * ultimately this is used to implement {@link javax.persistence.metamodel.IdentifiableType#getId} * and {@link javax.persistence.metamodel.IdentifiableType#getDeclaredId}. However, the * "tricky" case here (non-aggregate cid) is one that JPA says should throw an * exception */ SingularPersistentAttribute asAttribute(Class javaType); IdentifierGenerator getIdentifierValueGenerator(); /** * Given a hydrated representation of this Readable, resolve its * domain representation. *

* E.g. for a composite, the hydrated form is an Object[] representing the * "simple state" of the composite's attributes. Resolution of those values * returns the instance of the component with its resolved values injected. * * @apiNote */ default Object resolveHydratedState( Object hydratedForm, ExecutionContext executionContext, SharedSessionContractImplementor session, Object containerInstance) { throw new NotYetImplementedFor6Exception( getClass() ); } /** * Retrieve the columns making up the identifier */ List getColumns(); @Override default int getNumberOfJdbcParametersNeeded() { return getColumns().size(); } @Override default List resolveColumnReferences( ColumnReferenceQualifier qualifier, SqlAstCreationContext resolutionContext) { final ArrayList columnRefs = new ArrayList<>(); for ( Column column : getColumns() ) { // todo (6.0) - this there a better way to deal with this in the design? Expression expression = resolutionContext.getSqlSelectionResolver().resolveSqlExpression( qualifier, column ); if ( !ColumnReference.class.isInstance( expression ) ) { columnRefs.add( (ColumnReference) ( (SqlSelectionExpression) expression ).getExpression() ); } else { columnRefs.add( (ColumnReference) expression ); } } return columnRefs; } boolean matchesNavigableName(String navigableName); boolean canContainSubGraphs(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy