HHH-8805 HHH-7916 Support @Index(NO_CONSTRAINT) and @NotFound(IGNORE)
This commit is contained in:
parent
8945e9e590
commit
4651a064fa
|
@ -23,6 +23,9 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.internal.binder;
|
||||
|
||||
import static org.hibernate.MultiTenancyStrategy.DISCRIMINATOR;
|
||||
import static org.hibernate.engine.spi.SyntheticAttributeHelper.SYNTHETIC_COMPOSITE_ID_ATTRIBUTE_NAME;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
|
@ -60,6 +63,7 @@ import org.hibernate.id.PersistentIdentifierGenerator;
|
|||
import org.hibernate.id.enhanced.TableGenerator;
|
||||
import org.hibernate.internal.FilterConfiguration;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.metamodel.internal.binder.HibernateTypeHelper.ReflectedCollectionJavaTypes;
|
||||
import org.hibernate.metamodel.internal.resolver.AssociationRelationalBindingResolver;
|
||||
import org.hibernate.metamodel.internal.resolver.MappedByAssociationRelationalBindingResolverImpl;
|
||||
import org.hibernate.metamodel.internal.resolver.StandardAssociationRelationalBindingResolverImpl;
|
||||
|
@ -165,13 +169,8 @@ import org.hibernate.tuple.component.ComponentTuplizer;
|
|||
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||
import org.hibernate.type.ForeignKeyDirection;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import org.jboss.jandex.DotName;
|
||||
|
||||
import static org.hibernate.MultiTenancyStrategy.DISCRIMINATOR;
|
||||
import static org.hibernate.engine.spi.SyntheticAttributeHelper.SYNTHETIC_COMPOSITE_ID_ATTRIBUTE_NAME;
|
||||
import static org.hibernate.metamodel.internal.binder.HibernateTypeHelper.ReflectedCollectionJavaTypes;
|
||||
|
||||
/**
|
||||
* The common binder shared between annotations and {@code hbm.xml} processing.
|
||||
*
|
||||
|
@ -753,7 +752,8 @@ public class Binder {
|
|||
joinRelationalValueBindings,
|
||||
foreignKeyHelper().determineForeignKeyTargetTable( entityBinding, secondaryTableSource ),
|
||||
targetColumns,
|
||||
secondaryTableSource.isCascadeDeleteEnabled()
|
||||
secondaryTableSource.isCascadeDeleteEnabled(),
|
||||
secondaryTableSource.createForeignKeyConstraint()
|
||||
);
|
||||
SecondaryTable secondaryTable = new SecondaryTable( table, foreignKey );
|
||||
if ( secondaryTableSource.getFetchStyle()!=null ) {
|
||||
|
@ -1002,7 +1002,8 @@ public class Binder {
|
|||
subclassEntitySource
|
||||
),
|
||||
targetColumns,
|
||||
subclassEntitySource.isCascadeDeleteEnabled()
|
||||
subclassEntitySource.isCascadeDeleteEnabled(),
|
||||
subclassEntitySource.createForeignKeyConstraint()
|
||||
);
|
||||
|
||||
if ( subclassEntitySource.isCascadeDeleteEnabled() ) {
|
||||
|
@ -1461,7 +1462,8 @@ public class Binder {
|
|||
extractColumnsFromRelationalValueBindings( ownerAssociationAttributeBinding.getRelationalValueBindings() ),
|
||||
entityBinding.getPrimaryTable(),
|
||||
targetColumns,
|
||||
attributeSource.isCascadeDeleteEnabled()
|
||||
attributeSource.isCascadeDeleteEnabled(),
|
||||
true
|
||||
);
|
||||
if ( foreignKey == null ) {
|
||||
throw new AssertionFailure( "Foreign key not found; should have been defined by owner side of association." );
|
||||
|
@ -1553,14 +1555,16 @@ public class Binder {
|
|||
final List<RelationalValueBinding> sourceRelationalValueBindings,
|
||||
final TableSpecification targetTable,
|
||||
final List<Column> targetColumns,
|
||||
boolean isCascadeDeleteEnabled) {
|
||||
boolean isCascadeDeleteEnabled,
|
||||
boolean createConstraint) {
|
||||
return foreignKeyHelper().locateOrCreateForeignKey(
|
||||
foreignKeyName,
|
||||
sourceTable,
|
||||
extractColumnsFromRelationalValueBindings( sourceRelationalValueBindings ),
|
||||
targetTable,
|
||||
targetColumns,
|
||||
isCascadeDeleteEnabled
|
||||
isCascadeDeleteEnabled,
|
||||
createConstraint
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1840,16 +1844,6 @@ public class Binder {
|
|||
return attributeBinding;
|
||||
}
|
||||
|
||||
/**
|
||||
* todo: if the not found exception is ignored, here we should create an unique key instead of FK
|
||||
* this guard method should be removed after we implement this.
|
||||
*/
|
||||
private void throwExceptionIfNotFoundIgnored(boolean isNotFoundAnException) {
|
||||
if ( !isNotFoundAnException ) {
|
||||
throw new NotYetImplementedException( "association of ignored not found exception is not yet implemented" );
|
||||
}
|
||||
}
|
||||
|
||||
private ManyToOneAttributeBinding bindManyToOneAttribute(
|
||||
final AttributeBindingContainer attributeBindingContainer,
|
||||
final ToOneAttributeSource attributeSource,
|
||||
|
@ -1857,7 +1851,6 @@ public class Binder {
|
|||
if ( attribute == null ) {
|
||||
attribute = createSingularAttribute( attributeBindingContainer, attributeSource );
|
||||
}
|
||||
throwExceptionIfNotFoundIgnored( attributeSource.isNotFoundAnException() );
|
||||
|
||||
final JavaTypeDescriptor referencedEntityTypeDescriptor = typeHelper().determineJavaType(
|
||||
attributeSource,
|
||||
|
@ -1885,7 +1878,7 @@ public class Binder {
|
|||
propertyAccessorName( attributeSource ),
|
||||
attributeSource.isIncludedInOptimisticLocking(),
|
||||
attributeSource.isLazy(),
|
||||
attributeSource.isNotFoundAnException(),
|
||||
attributeSource.isIgnoreNotFound(),
|
||||
attributeSource.getNaturalIdMutability(),
|
||||
createMetaAttributeContext( attributeBindingContainer, attributeSource ),
|
||||
referencedEntityBinding,
|
||||
|
@ -1936,7 +1929,7 @@ public class Binder {
|
|||
uniqueKeyAttributeName,
|
||||
attributeSource.getFetchTiming() != FetchTiming.IMMEDIATE,
|
||||
attributeSource.isUnWrapProxy(),
|
||||
!attributeSource.isNotFoundAnException(),
|
||||
attributeSource.isIgnoreNotFound(),
|
||||
attributeSource.isUnique()
|
||||
);
|
||||
typeHelper().bindHibernateTypeDescriptor(
|
||||
|
@ -2558,7 +2551,6 @@ public class Binder {
|
|||
final OneToManyPluralAttributeElementSource elementSource,
|
||||
final EntityBinding referencedEntityBinding,
|
||||
final JavaTypeDescriptor defaultElementTypeDescriptor) {
|
||||
throwExceptionIfNotFoundIgnored( elementSource.isNotFoundAnException() );
|
||||
elementBinding.setElementEntityIdentifier(
|
||||
referencedEntityBinding.getKeyRelationalValueBindings()
|
||||
);
|
||||
|
@ -2569,7 +2561,7 @@ public class Binder {
|
|||
null,
|
||||
false,
|
||||
false,
|
||||
!elementSource.isNotFoundAnException(), //TODO: should be attributeBinding.isIgnoreNotFound(),
|
||||
elementSource.isIgnoreNotFound(),
|
||||
false
|
||||
);
|
||||
final HibernateTypeDescriptor hibernateTypeDescriptor = elementBinding.getHibernateTypeDescriptor();
|
||||
|
@ -2597,7 +2589,6 @@ public class Binder {
|
|||
final ManyToManyPluralAttributeElementSource elementSource,
|
||||
final EntityBinding referencedEntityBinding,
|
||||
final JavaTypeDescriptor defaultElementTypeDescriptor) {
|
||||
throwExceptionIfNotFoundIgnored( elementSource.isNotFoundAnException() );
|
||||
final TableSpecification collectionTable =
|
||||
elementBinding.getPluralAttributeBinding().getPluralAttributeKeyBinding().getCollectionTable();
|
||||
final AssociationRelationalBindingResolver resolver = getAssociationRelationalBindingResolver(
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* JBoss, Home of Professional Open Source
|
||||
* Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @authors tag. All rights reserved.
|
||||
* See the copyright.txt in the distribution for a
|
||||
* full listing of individual contributors.
|
||||
*
|
||||
* 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, v. 2.1.
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT A
|
||||
* 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,
|
||||
* v.2.1 along with this distribution; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
package org.hibernate.metamodel.internal.binder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.ConstraintMode;
|
||||
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.metamodel.source.internal.annotations.util.JPADotNames;
|
||||
import org.hibernate.metamodel.source.internal.annotations.util.JandexHelper;
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.jandex.DotName;
|
||||
|
||||
/**
|
||||
* @author Brett Meyer
|
||||
*/
|
||||
public class ForeignKeyDelegate {
|
||||
|
||||
private String explicitForeignKeyName = null;
|
||||
|
||||
private String inverseForeignKeyName = null;
|
||||
|
||||
private boolean createForeignKeyConstraint = true;
|
||||
|
||||
// TODO: do we need inverseCreateForeignKeyConstraint?
|
||||
|
||||
public ForeignKeyDelegate() {
|
||||
}
|
||||
|
||||
public ForeignKeyDelegate(Map<DotName, AnnotationInstance> annotations, ClassLoaderService cls) {
|
||||
final AnnotationInstance joinColumnAnnotation = annotations.get( JPADotNames.JOIN_COLUMN );
|
||||
final AnnotationInstance joinTable = annotations.get( JPADotNames.JOIN_TABLE );
|
||||
final AnnotationInstance collectionTable = annotations.get( JPADotNames.COLLECTION_TABLE );
|
||||
|
||||
if ( joinColumnAnnotation != null ) {
|
||||
resolveExplicitName( joinColumnAnnotation, cls );
|
||||
resolveCreateForeignKeyConstraint( joinColumnAnnotation, cls );
|
||||
}
|
||||
if ( joinTable != null ) {
|
||||
resolveExplicitName( joinTable, cls );
|
||||
resolveInverseName( joinTable, cls );
|
||||
resolveCreateForeignKeyConstraint( joinTable, cls );
|
||||
}
|
||||
if ( collectionTable != null ) {
|
||||
resolveExplicitName( collectionTable, cls );
|
||||
resolveCreateForeignKeyConstraint( collectionTable, cls );
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveExplicitName(AnnotationInstance owningAnnotation, ClassLoaderService cls) {
|
||||
AnnotationInstance jpaFkAnnotation = JandexHelper.getValue( owningAnnotation, "foreignKey", AnnotationInstance.class, cls );
|
||||
explicitForeignKeyName = jpaFkAnnotation != null ? JandexHelper.getValue( jpaFkAnnotation, "name", String.class, cls ) : null;
|
||||
}
|
||||
|
||||
private void resolveInverseName(AnnotationInstance owningAnnotation, ClassLoaderService cls) {
|
||||
AnnotationInstance jpaFkAnnotation = JandexHelper.getValue( owningAnnotation, "inverseForeignKey", AnnotationInstance.class, cls );
|
||||
inverseForeignKeyName = jpaFkAnnotation != null ? JandexHelper.getValue( jpaFkAnnotation, "name", String.class, cls ) : null;
|
||||
}
|
||||
|
||||
private void resolveCreateForeignKeyConstraint(AnnotationInstance owningAnnotation, ClassLoaderService cls) {
|
||||
AnnotationInstance jpaFkAnnotation = JandexHelper.getValue( owningAnnotation, "foreignKey", AnnotationInstance.class, cls );
|
||||
if ( jpaFkAnnotation != null ) {
|
||||
ConstraintMode mode = JandexHelper.getEnumValue( jpaFkAnnotation, "value", ConstraintMode.class, cls );
|
||||
createForeignKeyConstraint = !mode.equals( ConstraintMode.NO_CONSTRAINT );
|
||||
}
|
||||
}
|
||||
|
||||
public String getExplicitForeignKeyName() {
|
||||
return explicitForeignKeyName;
|
||||
}
|
||||
|
||||
public String getInverseForeignKeyName() {
|
||||
return inverseForeignKeyName;
|
||||
}
|
||||
|
||||
public boolean createForeignKeyConstraint() {
|
||||
return createForeignKeyConstraint;
|
||||
}
|
||||
}
|
|
@ -155,7 +155,8 @@ public class ForeignKeyHelper {
|
|||
final List<Column> sourceColumns,
|
||||
final TableSpecification targetTable,
|
||||
final List<Column> targetColumns,
|
||||
boolean isCascadeDeleteEnabled) {
|
||||
boolean isCascadeDeleteEnabled,
|
||||
boolean createConstraint) {
|
||||
final String foreignKeyName = helperContext.relationalIdentifierHelper().normalizeDatabaseIdentifier(
|
||||
explicitForeignKeyName, new ForeignKeyNamingStrategyHelper(
|
||||
sourceTable, sourceColumns, targetTable, targetColumns ) );
|
||||
|
@ -163,7 +164,7 @@ public class ForeignKeyHelper {
|
|||
ForeignKey foreignKey = locateAndBindForeignKeyByName( foreignKeyName, sourceTable, sourceColumns, targetTable, targetColumns );
|
||||
if ( foreignKey == null ) {
|
||||
// no foreign key found; create one
|
||||
foreignKey = sourceTable.createForeignKey( targetTable, foreignKeyName );
|
||||
foreignKey = sourceTable.createForeignKey( targetTable, foreignKeyName, createConstraint );
|
||||
bindForeignKeyColumns( foreignKey, sourceTable, sourceColumns, targetTable, targetColumns );
|
||||
}
|
||||
if ( isCascadeDeleteEnabled ) {
|
||||
|
|
|
@ -439,7 +439,7 @@ class HibernateTypeHelper {
|
|||
elementSource.getReferencedEntityAttributeName(),
|
||||
false,
|
||||
false,
|
||||
!elementSource.isNotFoundAnException(),
|
||||
elementSource.isIgnoreNotFound(),
|
||||
false
|
||||
);
|
||||
final HibernateTypeDescriptor hibernateTypeDescriptor = elementBinding.getHibernateTypeDescriptor();
|
||||
|
|
|
@ -104,7 +104,8 @@ public class MappedByAssociationRelationalBindingResolverImpl implements Associa
|
|||
sourceColumns,
|
||||
targetTable,
|
||||
targetColumns,
|
||||
attributeSource.isCascadeDeleteEnabled()
|
||||
attributeSource.isCascadeDeleteEnabled(),
|
||||
attributeSource.createForeignKeyConstraint()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -134,7 +134,8 @@ public class StandardAssociationRelationalBindingResolverImpl implements Associa
|
|||
sourceColumns,
|
||||
targetTable,
|
||||
targetColumns,
|
||||
attributeSource.isCascadeDeleteEnabled()
|
||||
attributeSource.isCascadeDeleteEnabled(),
|
||||
attributeSource.createForeignKeyConstraint()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -392,7 +393,8 @@ public class StandardAssociationRelationalBindingResolverImpl implements Associa
|
|||
extractColumnsFromRelationalValueBindings( sourceRelationalValueBindings ),
|
||||
targetTable,
|
||||
targetColumns,
|
||||
foreignKeyContributingSource.isCascadeDeleteEnabled()
|
||||
foreignKeyContributingSource.isCascadeDeleteEnabled(),
|
||||
foreignKeyContributingSource.createForeignKeyConstraint()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -112,8 +112,8 @@ public abstract class AbstractSingularAssociationAttributeSource
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotFoundAnException() {
|
||||
return !getPersistentAttribute().getShouldIgnoreNotFound();
|
||||
public boolean isIgnoreNotFound() {
|
||||
return getPersistentAttribute().isIgnoreNotFound();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -51,8 +51,8 @@ public abstract class AbstractPluralAssociationElementSourceImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotFoundAnException() {
|
||||
return !pluralAssociationAttribute().getShouldIgnoreNotFound();
|
||||
public boolean isIgnoreNotFound() {
|
||||
return pluralAssociationAttribute().isIgnoreNotFound();
|
||||
}
|
||||
|
||||
public AttributeSource getAttributeSource() {
|
||||
|
|
|
@ -73,8 +73,8 @@ public abstract class AbstractToOneAttributeSourceImpl extends SingularAttribute
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotFoundAnException() {
|
||||
return !associationAttribute.getShouldIgnoreNotFound();
|
||||
public boolean isIgnoreNotFound() {
|
||||
return associationAttribute.isIgnoreNotFound();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -81,6 +81,11 @@ public class JoinedSubclassEntitySourceImpl extends SubclassEntitySourceImpl imp
|
|||
return getEntityClass().getExplicitForeignKeyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createForeignKeyConstraint() {
|
||||
return getEntityClass().createForeignKeyConstraint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinColumnResolutionDelegate getForeignKeyTargetColumnResolutionDelegate() {
|
||||
return fkColumnResolutionDelegate;
|
||||
|
|
|
@ -22,7 +22,13 @@ public class ManyToManyMappedByPluralAttributeElementSourceImpl
|
|||
|
||||
@Override
|
||||
public String getExplicitForeignKeyName() {
|
||||
throw new UnsupportedOperationException( "Not supported for attributes with mappedBy specified." ); }
|
||||
throw new UnsupportedOperationException( "Not supported for attributes with mappedBy specified." );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createForeignKeyConstraint() {
|
||||
throw new UnsupportedOperationException( "Not supported for attributes with mappedBy specified." );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCascadeDeleteEnabled() {
|
||||
|
|
|
@ -70,6 +70,11 @@ public class ManyToManyPluralAttributeElementSourceImpl
|
|||
return pluralAssociationAttribute().getInverseForeignKeyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createForeignKeyConstraint() {
|
||||
return pluralAssociationAttribute().createForeignKeyConstraint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCascadeDeleteEnabled() {
|
||||
return false;
|
||||
|
|
|
@ -73,6 +73,11 @@ public class PluralAttributeKeySourceImpl implements PluralAttributeKeySource {
|
|||
return attribute.getExplicitForeignKeyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createForeignKeyConstraint() {
|
||||
return attribute.createForeignKeyConstraint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinColumnResolutionDelegate getForeignKeyTargetColumnResolutionDelegate() {
|
||||
if ( attribute.getMappedByAttributeName() != null ) {
|
||||
|
|
|
@ -125,6 +125,12 @@ public class SecondaryTableSourceImpl implements SecondaryTableSource {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createForeignKeyConstraint() {
|
||||
// not supported from annotations, unless docs for @ForeignKey are wrong...
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinColumnResolutionDelegate getForeignKeyTargetColumnResolutionDelegate() {
|
||||
return fkColumnResolutionDelegate;
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
|||
import org.hibernate.cfg.NamingStrategy;
|
||||
import org.hibernate.cfg.NotYetImplementedException;
|
||||
import org.hibernate.metamodel.internal.binder.Binder;
|
||||
import org.hibernate.metamodel.internal.binder.ForeignKeyDelegate;
|
||||
import org.hibernate.metamodel.source.internal.annotations.attribute.AbstractPersistentAttribute;
|
||||
import org.hibernate.metamodel.source.internal.annotations.attribute.AssociationOverride;
|
||||
import org.hibernate.metamodel.source.internal.annotations.attribute.Column;
|
||||
|
@ -49,7 +50,6 @@ import org.hibernate.metamodel.spi.binding.AttributeBinding;
|
|||
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
import org.hibernate.metamodel.spi.relational.Value;
|
||||
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
|
||||
/**
|
||||
|
@ -59,10 +59,9 @@ import org.jboss.jandex.AnnotationInstance;
|
|||
public class ToOneAttributeSourceImpl extends AbstractToOneAttributeSourceImpl implements ToOneAttributeSource {
|
||||
private final List<RelationalValueSource> relationalValueSources;
|
||||
private final String containingTableName;
|
||||
private final String explicitForeignKeyName;
|
||||
|
||||
private final EntityBindingContext bindingContext;
|
||||
private final ClassLoaderService cls;
|
||||
private final ForeignKeyDelegate foreignKeyDelegate;
|
||||
|
||||
public ToOneAttributeSourceImpl(
|
||||
SingularAssociationAttribute associationAttribute,
|
||||
|
@ -85,7 +84,8 @@ public class ToOneAttributeSourceImpl extends AbstractToOneAttributeSourceImpl i
|
|||
// Need to initialize logicalJoinTableName before determining nature.
|
||||
this.containingTableName = resolveContainingTableName( associationAttribute, relationalValueSources );
|
||||
setNature( determineNatureIfPossible( associationAttribute ) );
|
||||
this.explicitForeignKeyName = resolveForeignKeyName( associationAttribute );
|
||||
this.foreignKeyDelegate = new ForeignKeyDelegate(
|
||||
associationAttribute().getBackingMember().getAnnotations(), cls);
|
||||
}
|
||||
|
||||
private Nature determineNatureIfPossible(
|
||||
|
@ -118,27 +118,6 @@ public class ToOneAttributeSourceImpl extends AbstractToOneAttributeSourceImpl i
|
|||
}
|
||||
}
|
||||
|
||||
private String resolveForeignKeyName(SingularAssociationAttribute attribute) {
|
||||
final AnnotationInstance joinColumnAnnotation = attribute.getBackingMember()
|
||||
.getAnnotations()
|
||||
.get( JPADotNames.JOIN_COLUMN );
|
||||
if ( joinColumnAnnotation == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final AnnotationInstance jpaFkAnnotation = JandexHelper.getValue(
|
||||
joinColumnAnnotation,
|
||||
"foreignKey",
|
||||
AnnotationInstance.class,
|
||||
cls
|
||||
);
|
||||
if ( jpaFkAnnotation == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return JandexHelper.getValue( jpaFkAnnotation, "name", String.class, cls );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolveToOneAttributeSource(AttributeSourceResolutionContext context) {
|
||||
if ( getNature() != null ) {
|
||||
|
@ -289,7 +268,12 @@ public class ToOneAttributeSourceImpl extends AbstractToOneAttributeSourceImpl i
|
|||
|
||||
@Override
|
||||
public String getExplicitForeignKeyName() {
|
||||
return explicitForeignKeyName;
|
||||
return foreignKeyDelegate.getExplicitForeignKeyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createForeignKeyConstraint() {
|
||||
return foreignKeyDelegate.createForeignKeyConstraint();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -120,6 +120,11 @@ public class ToOneMappedByAttributeSourceImpl
|
|||
throw new UnsupportedOperationException( "Not supported for a \"mappedBy\" association." );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createForeignKeyConstraint() {
|
||||
throw new UnsupportedOperationException( "Not supported for a \"mappedBy\" association." );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCascadeDeleteEnabled() {
|
||||
return false;
|
||||
|
|
|
@ -37,6 +37,6 @@ public interface AssociationAttribute {
|
|||
public boolean isOrphanRemoval();
|
||||
|
||||
public boolean isOptional();
|
||||
public boolean getShouldIgnoreNotFound();
|
||||
public boolean isIgnoreNotFound();
|
||||
public boolean isUnWrapProxy();
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.CascadeType;
|
||||
|
||||
|
@ -44,6 +45,7 @@ import org.hibernate.engine.FetchStyle;
|
|||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.mapping.PropertyGeneration;
|
||||
import org.hibernate.metamodel.internal.binder.ForeignKeyDelegate;
|
||||
import org.hibernate.metamodel.reflite.spi.ArrayDescriptor;
|
||||
import org.hibernate.metamodel.reflite.spi.JavaTypeDescriptor;
|
||||
import org.hibernate.metamodel.reflite.spi.MemberDescriptor;
|
||||
|
@ -64,7 +66,6 @@ import org.hibernate.metamodel.source.spi.PluralAttributeSource;
|
|||
import org.hibernate.metamodel.spi.binding.Caching;
|
||||
import org.hibernate.metamodel.spi.binding.CustomSQL;
|
||||
import org.hibernate.metamodel.spi.binding.IdentifierGeneratorDefinition;
|
||||
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.jandex.AnnotationValue;
|
||||
import org.jboss.jandex.DotName;
|
||||
|
@ -117,8 +118,7 @@ public class PluralAttribute
|
|||
|
||||
// information about the FK
|
||||
private final OnDeleteAction onDeleteAction;
|
||||
private String inverseForeignKeyName;
|
||||
private String explicitForeignKeyName;
|
||||
private final ForeignKeyDelegate foreignKeyDelegate;
|
||||
|
||||
private final AttributeTypeResolver collectionTypeResolver;
|
||||
|
||||
|
@ -132,6 +132,8 @@ public class PluralAttribute
|
|||
private ArrayList<Column> joinColumnValues = new ArrayList<Column>();
|
||||
private ArrayList<Column> inverseJoinColumnValues = new ArrayList<Column>();
|
||||
|
||||
private final ClassLoaderService classLoaderService;
|
||||
|
||||
public PluralAttribute(
|
||||
ManagedTypeMetadata container,
|
||||
String name,
|
||||
|
@ -154,6 +156,8 @@ public class PluralAttribute
|
|||
accessorStrategy
|
||||
);
|
||||
|
||||
this.classLoaderService = getContext().getServiceRegistry().getService( ClassLoaderService.class );
|
||||
|
||||
// just to get the error the test expects
|
||||
// todo : I'd really rather see this driven from the class-level, not the attribute-level
|
||||
AssociationHelper.INSTANCE.determineMapsId(
|
||||
|
@ -204,24 +208,7 @@ public class PluralAttribute
|
|||
this.whereClause = determineWereClause( backingMember );
|
||||
this.orderBy = determineOrderBy( backingMember );
|
||||
|
||||
final AnnotationInstance joinTable = backingMember.getAnnotations().get( JPADotNames.JOIN_TABLE );
|
||||
final AnnotationInstance collectionTable = backingMember.getAnnotations().get( JPADotNames.COLLECTION_TABLE );
|
||||
if ( joinTable != null ) {
|
||||
AnnotationInstance jpaFkAnnotation = JandexHelper.extractAnnotationValue( joinTable, "foreignKey" );
|
||||
this.explicitForeignKeyName = jpaFkAnnotation != null
|
||||
? jpaFkAnnotation.value( "name" ).asString()
|
||||
: null;
|
||||
jpaFkAnnotation = JandexHelper.extractAnnotationValue( joinTable, "inverseForeignKey" );
|
||||
this.inverseForeignKeyName = jpaFkAnnotation != null
|
||||
? jpaFkAnnotation.value( "name" ).asString()
|
||||
: null;
|
||||
}
|
||||
if ( collectionTable != null) {
|
||||
final AnnotationInstance jpaFkAnnotation = JandexHelper.extractAnnotationValue( collectionTable, "foreignKey" );
|
||||
explicitForeignKeyName = jpaFkAnnotation != null
|
||||
? jpaFkAnnotation.value( "name" ).asString()
|
||||
: null;
|
||||
}
|
||||
this.foreignKeyDelegate = new ForeignKeyDelegate( backingMember.getAnnotations(), classLoaderService );
|
||||
|
||||
this.caching = determineCachingSettings( backingMember );
|
||||
|
||||
|
@ -331,7 +318,7 @@ public class PluralAttribute
|
|||
collectionId,
|
||||
"columns",
|
||||
AnnotationInstance[].class,
|
||||
getContext().getServiceRegistry().getService( ClassLoaderService.class )
|
||||
classLoaderService
|
||||
);
|
||||
final List<Column> idColumns = CollectionHelper.arrayList( columnAnnotations.length );
|
||||
for ( AnnotationInstance columnAnnotation : columnAnnotations ) {
|
||||
|
@ -346,7 +333,7 @@ public class PluralAttribute
|
|||
type,
|
||||
"parameters",
|
||||
AnnotationInstance[].class,
|
||||
getContext().getServiceRegistry().getService( ClassLoaderService.class )
|
||||
classLoaderService
|
||||
);
|
||||
if ( paramAnnotations == null || paramAnnotations.length == 0 ) {
|
||||
return Collections.emptyMap();
|
||||
|
@ -658,7 +645,7 @@ public class PluralAttribute
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean getShouldIgnoreNotFound() {
|
||||
public boolean isIgnoreNotFound() {
|
||||
return ignoreNotFound;
|
||||
}
|
||||
|
||||
|
@ -702,10 +689,13 @@ public class PluralAttribute
|
|||
}
|
||||
|
||||
public String getInverseForeignKeyName() {
|
||||
return inverseForeignKeyName;
|
||||
return foreignKeyDelegate.getInverseForeignKeyName();
|
||||
}
|
||||
public String getExplicitForeignKeyName(){
|
||||
return explicitForeignKeyName;
|
||||
return foreignKeyDelegate.getExplicitForeignKeyName();
|
||||
}
|
||||
public boolean createForeignKeyConstraint(){
|
||||
return foreignKeyDelegate.createForeignKeyConstraint();
|
||||
}
|
||||
|
||||
public Caching getCaching() {
|
||||
|
|
|
@ -25,6 +25,7 @@ package org.hibernate.metamodel.source.internal.annotations.attribute;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.CascadeType;
|
||||
|
||||
|
@ -40,7 +41,6 @@ import org.hibernate.metamodel.source.internal.annotations.util.HibernateDotName
|
|||
import org.hibernate.metamodel.source.internal.annotations.util.JPADotNames;
|
||||
import org.hibernate.metamodel.source.spi.AttributePath;
|
||||
import org.hibernate.metamodel.source.spi.AttributeRole;
|
||||
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
|
||||
/**
|
||||
|
@ -190,7 +190,7 @@ public class SingularAssociationAttribute
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean getShouldIgnoreNotFound() {
|
||||
public boolean isIgnoreNotFound() {
|
||||
return ignoreNotFound;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,13 +23,17 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.source.internal.annotations.entity;
|
||||
|
||||
import static org.hibernate.metamodel.source.internal.annotations.util.JPADotNames.ENTITY;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.AccessType;
|
||||
|
||||
import org.hibernate.annotations.OnDeleteAction;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.metamodel.internal.binder.ForeignKeyDelegate;
|
||||
import org.hibernate.metamodel.reflite.spi.ClassDescriptor;
|
||||
import org.hibernate.metamodel.reflite.spi.JavaTypeDescriptor;
|
||||
import org.hibernate.metamodel.source.internal.annotations.AnnotationBindingContext;
|
||||
|
@ -39,13 +43,10 @@ import org.hibernate.metamodel.source.internal.annotations.util.HibernateDotName
|
|||
import org.hibernate.metamodel.source.internal.annotations.util.JPADotNames;
|
||||
import org.hibernate.metamodel.source.internal.annotations.util.JandexHelper;
|
||||
import org.hibernate.metamodel.spi.binding.CustomSQL;
|
||||
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.jandex.AnnotationValue;
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
|
||||
import static org.hibernate.metamodel.source.internal.annotations.util.JPADotNames.ENTITY;
|
||||
|
||||
/**
|
||||
* Representation of metadata (configured via annotations or orm.xml) attached
|
||||
* to an Entity.
|
||||
|
@ -68,13 +69,11 @@ public class EntityTypeMetadata extends IdentifiableTypeMetadata {
|
|||
private final String discriminatorMatchValue;
|
||||
private final boolean isLazy;
|
||||
private final String proxy;
|
||||
private final ForeignKeyDelegate foreignKeyDelegate;
|
||||
|
||||
|
||||
private final ClassLoaderService classLoaderService;
|
||||
|
||||
// todo : ???
|
||||
|
||||
private final String inverseForeignKeyName;
|
||||
private final String explicitForeignKeyName;
|
||||
private final OnDeleteAction onDeleteAction;
|
||||
private final List<PrimaryKeyJoinColumn> joinedSubclassPrimaryKeyJoinColumnSources;
|
||||
|
||||
|
@ -88,6 +87,8 @@ public class EntityTypeMetadata extends IdentifiableTypeMetadata {
|
|||
AnnotationBindingContext bindingContext) {
|
||||
super( javaTypeDescriptor, defaultAccessType, true, bindingContext );
|
||||
|
||||
this.classLoaderService = bindingContext.getServiceRegistry().getService( ClassLoaderService.class );
|
||||
|
||||
this.explicitEntityName = determineExplicitEntityName();
|
||||
this.customLoaderQueryName = determineCustomLoader();
|
||||
this.synchronizedTableNames = determineSynchronizedTableNames();
|
||||
|
@ -119,7 +120,7 @@ public class EntityTypeMetadata extends IdentifiableTypeMetadata {
|
|||
dynamicInsertAnnotation,
|
||||
"value",
|
||||
Boolean.class,
|
||||
getLocalBindingContext().getServiceRegistry().getService( ClassLoaderService.class )
|
||||
classLoaderService
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -136,7 +137,7 @@ public class EntityTypeMetadata extends IdentifiableTypeMetadata {
|
|||
dynamicUpdateAnnotation,
|
||||
"value",
|
||||
Boolean.class,
|
||||
getLocalBindingContext().getServiceRegistry().getService( ClassLoaderService.class )
|
||||
classLoaderService
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -154,7 +155,7 @@ public class EntityTypeMetadata extends IdentifiableTypeMetadata {
|
|||
selectBeforeUpdateAnnotation,
|
||||
"value",
|
||||
Boolean.class,
|
||||
getLocalBindingContext().getServiceRegistry().getService( ClassLoaderService.class )
|
||||
classLoaderService
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -206,13 +207,13 @@ public class EntityTypeMetadata extends IdentifiableTypeMetadata {
|
|||
this.discriminatorMatchValue = null;
|
||||
}
|
||||
|
||||
// TODO: bind JPA @ForeignKey?
|
||||
foreignKeyDelegate = new ForeignKeyDelegate();
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// todo : which (if any) of these to keep?
|
||||
this.joinedSubclassPrimaryKeyJoinColumnSources = determinePrimaryKeyJoinColumns();
|
||||
// TODO: bind JPA @ForeignKey?
|
||||
this.explicitForeignKeyName = null;
|
||||
this.inverseForeignKeyName = null;
|
||||
this.onDeleteAction = determineOnDeleteAction();
|
||||
}
|
||||
|
||||
|
@ -227,6 +228,7 @@ public class EntityTypeMetadata extends IdentifiableTypeMetadata {
|
|||
AnnotationBindingContext bindingContext) {
|
||||
super( javaTypeDescriptor, superType, defaultAccessType, bindingContext );
|
||||
|
||||
this.classLoaderService = bindingContext.getServiceRegistry().getService( ClassLoaderService.class );
|
||||
|
||||
this.explicitEntityName = determineExplicitEntityName();
|
||||
this.customLoaderQueryName = determineCustomLoader();
|
||||
|
@ -259,7 +261,7 @@ public class EntityTypeMetadata extends IdentifiableTypeMetadata {
|
|||
dynamicInsertAnnotation,
|
||||
"value",
|
||||
Boolean.class,
|
||||
getLocalBindingContext().getServiceRegistry().getService( ClassLoaderService.class )
|
||||
classLoaderService
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -276,7 +278,7 @@ public class EntityTypeMetadata extends IdentifiableTypeMetadata {
|
|||
dynamicUpdateAnnotation,
|
||||
"value",
|
||||
Boolean.class,
|
||||
getLocalBindingContext().getServiceRegistry().getService( ClassLoaderService.class )
|
||||
classLoaderService
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -294,7 +296,7 @@ public class EntityTypeMetadata extends IdentifiableTypeMetadata {
|
|||
selectBeforeUpdateAnnotation,
|
||||
"value",
|
||||
Boolean.class,
|
||||
getLocalBindingContext().getServiceRegistry().getService( ClassLoaderService.class )
|
||||
classLoaderService
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -346,13 +348,13 @@ public class EntityTypeMetadata extends IdentifiableTypeMetadata {
|
|||
this.discriminatorMatchValue = null;
|
||||
}
|
||||
|
||||
// TODO: bind JPA @ForeignKey?
|
||||
foreignKeyDelegate = new ForeignKeyDelegate();
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// todo : which (if any) of these to keep?
|
||||
this.joinedSubclassPrimaryKeyJoinColumnSources = determinePrimaryKeyJoinColumns();
|
||||
// TODO: bind JPA @ForeignKey?
|
||||
this.explicitForeignKeyName = null;
|
||||
this.inverseForeignKeyName = null;
|
||||
this.onDeleteAction = determineOnDeleteAction();
|
||||
}
|
||||
|
||||
|
@ -422,7 +424,7 @@ public class EntityTypeMetadata extends IdentifiableTypeMetadata {
|
|||
onDeleteAnnotation,
|
||||
"action",
|
||||
OnDeleteAction.class,
|
||||
getLocalBindingContext().getServiceRegistry().getService( ClassLoaderService.class )
|
||||
classLoaderService
|
||||
);
|
||||
}
|
||||
return null;
|
||||
|
@ -499,10 +501,13 @@ public class EntityTypeMetadata extends IdentifiableTypeMetadata {
|
|||
|
||||
|
||||
public String getInverseForeignKeyName() {
|
||||
return inverseForeignKeyName;
|
||||
return foreignKeyDelegate.getInverseForeignKeyName();
|
||||
}
|
||||
public String getExplicitForeignKeyName(){
|
||||
return explicitForeignKeyName;
|
||||
return foreignKeyDelegate.getExplicitForeignKeyName();
|
||||
}
|
||||
public boolean createForeignKeyConstraint(){
|
||||
return foreignKeyDelegate.createForeignKeyConstraint();
|
||||
}
|
||||
|
||||
public OnDeleteAction getOnDeleteAction() {
|
||||
|
|
|
@ -88,8 +88,8 @@ public abstract class AbstractToOneAttributeSourceImpl extends AbstractHbmSource
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotFoundAnException() {
|
||||
return true;
|
||||
public boolean isIgnoreNotFound() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -263,4 +263,10 @@ public abstract class AbstractToOneAttributeSourceImpl extends AbstractHbmSource
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createForeignKeyConstraint() {
|
||||
// TODO: Can HBM do something like JPA's @ForeignKey(NO_CONSTRAINT)?
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -94,6 +94,12 @@ public class JoinedSubclassEntitySourceImpl extends SubclassEntitySourceImpl imp
|
|||
return key.getForeignKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createForeignKeyConstraint() {
|
||||
// TODO: Can HBM do something like JPA's @ForeignKey(NO_CONSTRAINT)?
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinColumnResolutionDelegate getForeignKeyTargetColumnResolutionDelegate() {
|
||||
return key.getPropertyRef() == null
|
||||
|
@ -116,7 +122,6 @@ public class JoinedSubclassEntitySourceImpl extends SubclassEntitySourceImpl imp
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<ColumnSource> getPrimaryKeyColumnSources() {
|
||||
return primaryKeyJoinColumnSources;
|
||||
|
|
|
@ -140,8 +140,8 @@ public class ManyToManyPluralAttributeElementSourceImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotFoundAnException() {
|
||||
return manyToManyElement.getNotFound() == null || !"ignore".equals( manyToManyElement.getNotFound().value() );
|
||||
public boolean isIgnoreNotFound() {
|
||||
return manyToManyElement.getNotFound() != null && "ignore".equalsIgnoreCase( manyToManyElement.getNotFound().value() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -258,4 +258,10 @@ public class ManyToManyPluralAttributeElementSourceImpl
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createForeignKeyConstraint() {
|
||||
// TODO: Can HBM do something like JPA's @ForeignKey(NO_CONSTRAINT)?
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -105,8 +105,8 @@ class ManyToOneAttributeSourceImpl extends AbstractToOneAttributeSourceImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotFoundAnException() {
|
||||
return manyToOneElement.getNotFound() == null || !"ignore".equals( manyToOneElement.getNotFound().value() );
|
||||
public boolean isIgnoreNotFound() {
|
||||
return manyToOneElement.getNotFound() != null && "ignore".equalsIgnoreCase( manyToOneElement.getNotFound().value() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -63,9 +63,8 @@ public class OneToManyPluralAttributeElementSourceImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotFoundAnException() {
|
||||
return oneToManyElement.getNotFound() == null
|
||||
|| ! "ignore".equals( oneToManyElement.getNotFound().value() );
|
||||
public boolean isIgnoreNotFound() {
|
||||
return oneToManyElement.getNotFound() != null && "ignore".equalsIgnoreCase( oneToManyElement.getNotFound().value() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -86,6 +86,12 @@ public class PluralAttributeKeySourceImpl
|
|||
return keyElement.getForeignKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createForeignKeyConstraint() {
|
||||
// TODO: Can HBM do something like JPA's @ForeignKey(NO_CONSTRAINT)?
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinColumnResolutionDelegate getForeignKeyTargetColumnResolutionDelegate() {
|
||||
return keyElement.getPropertyRef() == null
|
||||
|
|
|
@ -141,6 +141,12 @@ class SecondaryTableSourceImpl extends AbstractHbmSourceNode implements Secondar
|
|||
return joinElement.getKey().getForeignKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createForeignKeyConstraint() {
|
||||
// TODO: Can HBM do something like JPA's @ForeignKey(NO_CONSTRAINT)?
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinColumnResolutionDelegate getForeignKeyTargetColumnResolutionDelegate() {
|
||||
return fkJoinColumnResolutionDelegate;
|
||||
|
|
|
@ -39,7 +39,7 @@ public interface AssociationSource extends CascadeStyleSource {
|
|||
*/
|
||||
public String getReferencedEntityName();
|
||||
|
||||
public boolean isNotFoundAnException();
|
||||
public boolean isIgnoreNotFound();
|
||||
|
||||
/**
|
||||
* Returns the attribute source that is owned by this {@link AssociationSource},
|
||||
|
|
|
@ -42,6 +42,13 @@ public interface ForeignKeyContributingSource {
|
|||
*/
|
||||
public String getExplicitForeignKeyName();
|
||||
|
||||
/**
|
||||
* Primarily exists to support JPA's @ForeignKey(NO_CONSTRAINT).
|
||||
*
|
||||
* @return True if the FK constraint should be created, false if not.
|
||||
*/
|
||||
public boolean createForeignKeyConstraint();
|
||||
|
||||
/**
|
||||
* Is "cascade delete" enabled for the foreign key? In other words, if a record in the parent (referenced)
|
||||
* table is deleted, should the corresponding records in the child table automatically be deleted?
|
||||
|
|
|
@ -34,7 +34,7 @@ public interface ManyToManyPluralAttributeElementSource
|
|||
|
||||
public String getReferencedEntityAttributeName();
|
||||
|
||||
public boolean isNotFoundAnException();
|
||||
public boolean isIgnoreNotFound();
|
||||
|
||||
public String getExplicitForeignKeyName();
|
||||
|
||||
|
|
|
@ -29,5 +29,5 @@ package org.hibernate.metamodel.source.spi;
|
|||
public interface OneToManyPluralAttributeElementSource extends PluralAttributeElementSource, AssociationSource {
|
||||
public String getReferencedEntityName();
|
||||
|
||||
public boolean isNotFoundAnException();
|
||||
public boolean isIgnoreNotFound();
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ public abstract class AbstractAttributeBindingContainer implements AttributeBind
|
|||
String propertyAccessorName,
|
||||
boolean includedInOptimisticLocking,
|
||||
boolean lazy,
|
||||
boolean isNotFoundAnException,
|
||||
boolean isIgnoreNotFound,
|
||||
SingularAttributeBinding.NaturalIdMutability naturalIdMutability,
|
||||
MetaAttributeContext metaAttributeContext,
|
||||
EntityBinding referencedEntityBinding,
|
||||
|
@ -192,7 +192,7 @@ public abstract class AbstractAttributeBindingContainer implements AttributeBind
|
|||
propertyAccessorName,
|
||||
includedInOptimisticLocking,
|
||||
lazy,
|
||||
isNotFoundAnException,
|
||||
isIgnoreNotFound,
|
||||
naturalIdMutability,
|
||||
metaAttributeContext,
|
||||
referencedEntityBinding,
|
||||
|
|
|
@ -186,7 +186,7 @@ public abstract class AbstractCompositeAttributeBindingContainer
|
|||
String propertyAccessorName,
|
||||
boolean includedInOptimisticLocking,
|
||||
boolean lazy,
|
||||
boolean isNotFoundAnException,
|
||||
boolean isIgnoreNotFound,
|
||||
SingularAttributeBinding.NaturalIdMutability naturalIdMutability,
|
||||
MetaAttributeContext metaAttributeContext,
|
||||
EntityBinding referencedEntityBinding,
|
||||
|
@ -199,7 +199,7 @@ public abstract class AbstractCompositeAttributeBindingContainer
|
|||
propertyAccessorName,
|
||||
includedInOptimisticLocking,
|
||||
lazy,
|
||||
isNotFoundAnException,
|
||||
isIgnoreNotFound,
|
||||
naturalIdMutability,
|
||||
metaAttributeContext,
|
||||
referencedEntityBinding,
|
||||
|
|
|
@ -48,7 +48,7 @@ public abstract class AbstractSingularAssociationAttributeBinding extends Abstra
|
|||
private FetchTiming fetchTiming;
|
||||
private FetchStyle fetchStyle;
|
||||
private boolean isUnWrapProxy;
|
||||
private final boolean isNotFoundAnException;
|
||||
private final boolean isIgnoreNotFound;
|
||||
|
||||
public AbstractSingularAssociationAttributeBinding(
|
||||
AttributeBindingContainer container,
|
||||
|
@ -56,7 +56,7 @@ public abstract class AbstractSingularAssociationAttributeBinding extends Abstra
|
|||
String propertyAccessorName,
|
||||
boolean includedInOptimisticLocking,
|
||||
boolean isLazy,
|
||||
boolean isNotFoundAnException,
|
||||
boolean isIgnoreNotFound,
|
||||
NaturalIdMutability naturalIdMutability,
|
||||
MetaAttributeContext metaAttributeContext,
|
||||
EntityBinding referencedEntityBinding,
|
||||
|
@ -78,12 +78,12 @@ public abstract class AbstractSingularAssociationAttributeBinding extends Abstra
|
|||
}
|
||||
this.referencedEntityBinding = referencedEntityBinding;
|
||||
this.referencedAttributeBinding = referencedAttributeBinding;
|
||||
this.isNotFoundAnException = isNotFoundAnException;
|
||||
this.isIgnoreNotFound = isIgnoreNotFound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotFoundAnException() {
|
||||
return isNotFoundAnException;
|
||||
public boolean isIgnoreNotFound() {
|
||||
return isIgnoreNotFound;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -207,7 +207,7 @@ public interface AttributeBindingContainer {
|
|||
String propertyAccessorName,
|
||||
boolean includedInOptimisticLocking,
|
||||
boolean lazy,
|
||||
boolean isNotFoundAnException,
|
||||
boolean isIgnoreNotFound,
|
||||
SingularAttributeBinding.NaturalIdMutability naturalIdMutability,
|
||||
MetaAttributeContext metaAttributeContext,
|
||||
EntityBinding referencedEntityBinding,
|
||||
|
|
|
@ -438,7 +438,7 @@ public class CompositeAttributeBinding
|
|||
String propertyAccessorName,
|
||||
boolean includedInOptimisticLocking,
|
||||
boolean lazy,
|
||||
boolean isNotFoundAnException,
|
||||
boolean isIgnoreNotFound,
|
||||
NaturalIdMutability naturalIdMutability,
|
||||
MetaAttributeContext metaAttributeContext,
|
||||
EntityBinding referencedEntityBinding,
|
||||
|
@ -448,7 +448,7 @@ public class CompositeAttributeBinding
|
|||
propertyAccessorName,
|
||||
includedInOptimisticLocking,
|
||||
lazy,
|
||||
isNotFoundAnException,
|
||||
isIgnoreNotFound,
|
||||
naturalIdMutability,
|
||||
metaAttributeContext,
|
||||
referencedEntityBinding,
|
||||
|
|
|
@ -41,7 +41,7 @@ public class ManyToOneAttributeBinding
|
|||
String propertyAccessorName,
|
||||
boolean includedInOptimisticLocking,
|
||||
boolean lazy,
|
||||
boolean isNotFoundAnException,
|
||||
boolean isIgnoreNotFound,
|
||||
NaturalIdMutability naturalIdMutability,
|
||||
MetaAttributeContext metaAttributeContext,
|
||||
EntityBinding referencedEntityBinding,
|
||||
|
@ -52,7 +52,7 @@ public class ManyToOneAttributeBinding
|
|||
propertyAccessorName,
|
||||
includedInOptimisticLocking,
|
||||
lazy,
|
||||
isNotFoundAnException,
|
||||
isIgnoreNotFound,
|
||||
naturalIdMutability,
|
||||
metaAttributeContext,
|
||||
referencedEntityBinding,
|
||||
|
|
|
@ -52,7 +52,7 @@ public class OneToOneAttributeBinding
|
|||
propertyAccessorName,
|
||||
includedInOptimisticLocking,
|
||||
lazy,
|
||||
true, //always true
|
||||
false,
|
||||
naturalIdMutability,
|
||||
metaAttributeContext,
|
||||
referencedEntityBinding,
|
||||
|
|
|
@ -45,7 +45,7 @@ public interface SingularAssociationAttributeBinding extends SingularAttributeBi
|
|||
|
||||
public SingularAttributeBinding getReferencedAttributeBinding();
|
||||
|
||||
public boolean isNotFoundAnException();
|
||||
public boolean isIgnoreNotFound();
|
||||
|
||||
public TableSpecification getTable();
|
||||
|
||||
|
|
|
@ -166,8 +166,8 @@ public abstract class AbstractTableSpecification implements TableSpecification {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ForeignKey createForeignKey(TableSpecification targetTable, String name) {
|
||||
ForeignKey fk = new ForeignKey( this, targetTable, name );
|
||||
public ForeignKey createForeignKey(TableSpecification targetTable, String name, boolean createConstraint) {
|
||||
ForeignKey fk = new ForeignKey( this, targetTable, name, createConstraint );
|
||||
foreignKeys.add( fk );
|
||||
return fk;
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ public class DenormalizedTable extends Table {
|
|||
}
|
||||
|
||||
private void copyFK(ForeignKey fk, String fkName) {
|
||||
ForeignKey copiedFK = createForeignKey( fk.getTargetTable(), fkName );
|
||||
ForeignKey copiedFK = createForeignKey( fk.getTargetTable(), fkName, fk.createConstraint() );
|
||||
copiedFK.setDeleteRule( fk.getDeleteRule() );
|
||||
copiedFK.setUpdateRule( fk.getUpdateRule() );
|
||||
Iterable<ForeignKey.ColumnMapping> columnMappings = fk.getColumnMappings();
|
||||
|
|
|
@ -53,16 +53,20 @@ public class ForeignKey extends AbstractConstraint {
|
|||
private ReferentialAction deleteRule = ReferentialAction.NO_ACTION;
|
||||
private ReferentialAction updateRule = ReferentialAction.NO_ACTION;
|
||||
|
||||
protected ForeignKey(TableSpecification sourceTable, TableSpecification targetTable, String name) {
|
||||
private boolean createConstraint;
|
||||
|
||||
protected ForeignKey(TableSpecification sourceTable, TableSpecification targetTable, String name,
|
||||
boolean createConstraint) {
|
||||
super( sourceTable, name );
|
||||
if ( targetTable == null ) {
|
||||
throw new IllegalArgumentException( "targetTable must be non-null." );
|
||||
}
|
||||
this.targetTable = targetTable;
|
||||
this.createConstraint = createConstraint;
|
||||
}
|
||||
|
||||
protected ForeignKey(TableSpecification sourceTable, TableSpecification targetTable) {
|
||||
this( sourceTable, targetTable, null );
|
||||
this( sourceTable, targetTable, null, true );
|
||||
}
|
||||
|
||||
public TableSpecification getSourceTable() {
|
||||
|
@ -216,4 +220,8 @@ public class ForeignKey extends AbstractConstraint {
|
|||
public String getExportIdentifier() {
|
||||
return getSourceTable().getLoggableValueQualifier() + ".FK-" + getName();
|
||||
}
|
||||
|
||||
public boolean createConstraint() {
|
||||
return createConstraint;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,10 +129,11 @@ public interface TableSpecification extends ValueContainer, Loggable {
|
|||
*
|
||||
* @param targetTable The table that is the target of the foreign key
|
||||
* @param name The (optional) name of the foreign key
|
||||
* @param createConstraint
|
||||
*
|
||||
* @return The foreign key reference.
|
||||
*/
|
||||
public ForeignKey createForeignKey(TableSpecification targetTable, String name);
|
||||
public ForeignKey createForeignKey(TableSpecification targetTable, String name, boolean createConstraint);
|
||||
|
||||
public Iterable<Index> getIndexes();
|
||||
|
||||
|
|
|
@ -45,6 +45,10 @@ public class StandardForeignKeyExporter implements Exporter<ForeignKey> {
|
|||
return NO_COMMANDS;
|
||||
}
|
||||
|
||||
if ( ! foreignKey.createConstraint() ) {
|
||||
return NO_COMMANDS;
|
||||
}
|
||||
|
||||
final int numberOfColumns = foreignKey.getColumnSpan();
|
||||
final String[] columnNames = new String[ numberOfColumns ];
|
||||
final String[] targetColumnNames = new String[ numberOfColumns ];
|
||||
|
@ -96,6 +100,10 @@ public class StandardForeignKeyExporter implements Exporter<ForeignKey> {
|
|||
return NO_COMMANDS;
|
||||
}
|
||||
|
||||
if ( ! foreignKey.createConstraint() ) {
|
||||
return NO_COMMANDS;
|
||||
}
|
||||
|
||||
final String sourceTableName = jdbcEnvironment.getQualifiedObjectNameSupport().formatName(
|
||||
( (Table) foreignKey.getSourceTable() ).getTableName()
|
||||
);
|
||||
|
|
|
@ -110,7 +110,7 @@ public class TableManipulationTests extends BaseUnitTestCase {
|
|||
Column pageBookId = page.locateOrCreateColumn( "BOOK_ID" );
|
||||
pageId.setJdbcDataType( INTEGER );
|
||||
pageId.setSize( Size.precision( 18, 0 ) );
|
||||
ForeignKey pageBookFk = page.createForeignKey( book, "PAGE_BOOK_FK" );
|
||||
ForeignKey pageBookFk = page.createForeignKey( book, "PAGE_BOOK_FK", true );
|
||||
pageBookFk.addColumn( pageBookId );
|
||||
|
||||
assertEquals( page, pageBookFk.getSourceTable() );
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
//$Id$
|
||||
package org.hibernate.test.annotations.notfound;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
|
@ -37,7 +39,8 @@ public class Coin {
|
|||
}
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "currency", referencedColumnName = "name")
|
||||
@JoinColumn(name = "currency", referencedColumnName = "name",
|
||||
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
||||
@NotFound(action = NotFoundAction.IGNORE)
|
||||
public Currency getCurrency() {
|
||||
return currency;
|
||||
|
|
|
@ -23,19 +23,16 @@
|
|||
*/
|
||||
package org.hibernate.test.annotations.notfound;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
import static org.junit.Assert.assertNull;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@FailureExpectedWithNewMetamodel(jiraKey = "HHH-7916")
|
||||
public class NotFoundTest extends BaseCoreFunctionalTestCase {
|
||||
@Test
|
||||
public void testManyToOne() throws Exception {
|
||||
|
|
|
@ -22,9 +22,13 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.collection.original;
|
||||
import java.sql.SQLException;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -33,17 +37,11 @@ import org.hibernate.Transaction;
|
|||
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
@FailureExpectedWithNewMetamodel(jiraKey = "HHH-7916")
|
||||
public class CollectionTest extends BaseCoreFunctionalTestCase {
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
|
@ -51,6 +49,7 @@ public class CollectionTest extends BaseCoreFunctionalTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@FailureExpectedWithNewMetamodel
|
||||
public void testExtraLazy() throws HibernateException, SQLException {
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
|
|
|
@ -23,24 +23,21 @@
|
|||
*/
|
||||
package org.hibernate.test.unconstrained;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
@FailureExpectedWithNewMetamodel(jiraKey = "HHH-7916")
|
||||
public class UnconstrainedTest extends BaseCoreFunctionalTestCase {
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
|
|
Loading…
Reference in New Issue