/* * 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.boot.model.source.internal.hbm; import java.util.List; import org.hibernate.boot.MappingException; import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmCompositeKeyManyToOneType; import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmLazyEnum; import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmLazyWithNoProxyEnum; import org.hibernate.boot.model.JavaTypeDescriptor; import org.hibernate.boot.model.source.spi.AttributePath; import org.hibernate.boot.model.source.spi.AttributeRole; import org.hibernate.boot.model.source.spi.AttributeSourceContainer; import org.hibernate.boot.model.source.spi.NaturalIdMutability; import org.hibernate.boot.model.source.spi.RelationalValueSource; import org.hibernate.boot.model.source.spi.RelationalValueSourceContainer; import org.hibernate.boot.model.source.spi.SingularAttributeNature; import org.hibernate.boot.model.source.spi.SingularAttributeSourceManyToOne; import org.hibernate.boot.model.source.spi.ToolingHintContext; import org.hibernate.type.ForeignKeyDirection; /** * Descriptor for {@code <key-many-to-one/>} mapping * * @author Steve Ebersole * @author Gail Badner */ public class CompositeIdentifierSingularAttributeSourceManyToOneImpl extends AbstractToOneAttributeSourceImpl implements SingularAttributeSourceManyToOne, RelationalValueSourceContainer { private final JaxbHbmCompositeKeyManyToOneType keyManyToOneElement; private final String referencedEntityName; private final HibernateTypeSourceImpl typeSource; private final List<RelationalValueSource> valueSources; private final AttributePath attributePath; private final AttributeRole attributeRole; private final FetchCharacteristicsSingularAssociationImpl fetchCharacteristics; private final ToolingHintContext toolingHintContext; public CompositeIdentifierSingularAttributeSourceManyToOneImpl( MappingDocument mappingDocument, AttributeSourceContainer container, final JaxbHbmCompositeKeyManyToOneType keyManyToOneElement) { super( mappingDocument, NaturalIdMutability.NOT_NATURAL_ID ); this.keyManyToOneElement = keyManyToOneElement; this.referencedEntityName = keyManyToOneElement.getClazz() != null ? mappingDocument.qualifyClassName( keyManyToOneElement.getClazz() ) : keyManyToOneElement.getEntityName(); final JavaTypeDescriptor referencedTypeDescriptor = new JavaTypeDescriptor() { @Override public String getName() { return referencedEntityName; } }; this.typeSource = new HibernateTypeSourceImpl( referencedTypeDescriptor ); this.valueSources = RelationalValueSourceHelper.buildValueSources( mappingDocument, null, new RelationalValueSourceHelper.AbstractColumnsAndFormulasSource() { @Override public XmlElementMetadata getSourceType() { return XmlElementMetadata.KEY_MANY_TO_ONE; } @Override public String getSourceName() { return keyManyToOneElement.getName(); } @Override public String getColumnAttribute() { return keyManyToOneElement.getColumnAttribute(); } @Override public List getColumnOrFormulaElements() { return keyManyToOneElement.getColumn(); } } ); this.attributePath = container.getAttributePathBase().append( getName() ); this.attributeRole = container.getAttributeRoleBase().append( getName() ); this.fetchCharacteristics = FetchCharacteristicsSingularAssociationImpl.interpretManyToOne( mappingDocument.getMappingDefaults(), null, null, interpretLazy( mappingDocument, keyManyToOneElement ) ); this.toolingHintContext = Helper.collectToolingHints( container.getToolingHintContext(), keyManyToOneElement ); } private static JaxbHbmLazyWithNoProxyEnum interpretLazy( MappingDocument mappingDocument, JaxbHbmCompositeKeyManyToOneType keyManyToOne) { if ( keyManyToOne.getLazy() == null ) { return null; } else if ( keyManyToOne.getLazy() == JaxbHbmLazyEnum.FALSE ) { return JaxbHbmLazyWithNoProxyEnum.FALSE; } else if ( keyManyToOne.getLazy() == JaxbHbmLazyEnum.PROXY ) { return JaxbHbmLazyWithNoProxyEnum.PROXY; } throw new MappingException( "Unrecognized lazy value [" + keyManyToOne.getLazy().name() + "] specified for key-many-to-one [" + keyManyToOne.getName() + "]", mappingDocument.getOrigin() ); } @Override public SingularAttributeNature getSingularAttributeNature() { return SingularAttributeNature.MANY_TO_ONE; } @Override public Boolean isInsertable() { return true; } @Override public Boolean isUpdatable() { return false; } @Override public boolean isBytecodeLazy() { return false; } @Override public XmlElementMetadata getSourceType() { return XmlElementMetadata.KEY_MANY_TO_ONE; } @Override public String getName() { return keyManyToOneElement.getName(); } @Override public String getXmlNodeName() { return null; } @Override public AttributePath getAttributePath() { return attributePath; } @Override public HibernateTypeSourceImpl getTypeInformation() { return typeSource; } @Override public String getPropertyAccessorName() { return keyManyToOneElement.getAccess(); } @Override public AttributeRole getAttributeRole() { return attributeRole; } @Override public List<RelationalValueSource> getRelationalValueSources() { return valueSources; } @Override public boolean areValuesIncludedInInsertByDefault() { return true; } @Override public boolean areValuesIncludedInUpdateByDefault() { return false; } @Override public boolean isIncludedInOptimisticLocking() { return false; } @Override public FetchCharacteristicsSingularAssociationImpl getFetchCharacteristics() { return fetchCharacteristics; } @Override public boolean isVirtualAttribute() { return false; } @Override public boolean areValuesNullableByDefault() { return false; } @Override public String getReferencedEntityAttributeName() { return null; } @Override public String getReferencedEntityName() { return referencedEntityName; } @Override public Boolean isEmbedXml() { return null; } @Override public boolean isUnique() { return false; } @Override public ForeignKeyDirection getForeignKeyDirection() { return ForeignKeyDirection.TO_PARENT; } @Override public String getCascadeStyleName() { return ""; } @Override public String getExplicitForeignKeyName() { return keyManyToOneElement.getForeignKey(); } @Override public boolean isCascadeDeleteEnabled() { return "cascade".equals( keyManyToOneElement.getOnDelete().value() ); } protected String getClassName() { return sourceMappingDocument().qualifyClassName( keyManyToOneElement.getClazz() ); } @Override public ToolingHintContext getToolingHintContext() { return toolingHintContext; } }