Search in sources :

Example 11 with Collection

use of org.hibernate.mapping.Collection in project hibernate-orm by hibernate.

the class ListBinder method bindIndex.

private void bindIndex(final MetadataBuildingContext buildingContext) {
    if (!indexColumn.isImplicit()) {
        PropertyHolder valueHolder = PropertyHolderBuilder.buildPropertyHolder(this.collection, StringHelper.qualify(this.collection.getRole(), "key"), null, null, propertyHolder, getBuildingContext());
        List list = (List) this.collection;
        if (!list.isOneToMany())
            indexColumn.forceNotNull();
        indexColumn.setPropertyHolder(valueHolder);
        SimpleValueBinder value = new SimpleValueBinder();
        value.setColumns(new Ejb3Column[] { indexColumn });
        value.setExplicitType("integer");
        value.setBuildingContext(getBuildingContext());
        SimpleValue indexValue = value.make();
        indexColumn.linkWithValue(indexValue);
        list.setIndex(indexValue);
        list.setBaseIndex(indexColumn.getBase());
        if (list.isOneToMany() && !list.getKey().isNullable() && !list.isInverse()) {
            String entityName = ((OneToMany) list.getElement()).getReferencedEntityName();
            PersistentClass referenced = buildingContext.getMetadataCollector().getEntityBinding(entityName);
            IndexBackref ib = new IndexBackref();
            ib.setName('_' + propertyName + "IndexBackref");
            ib.setUpdateable(false);
            ib.setSelectable(false);
            ib.setCollectionRole(list.getRole());
            ib.setEntityName(list.getOwner().getEntityName());
            ib.setValue(list.getIndex());
            referenced.addProperty(ib);
        }
    } else {
        Collection coll = this.collection;
        throw new AnnotationException("List/array has to be annotated with an @OrderColumn (or @IndexColumn): " + coll.getRole());
    }
}
Also used : PropertyHolder(org.hibernate.cfg.PropertyHolder) Collection(org.hibernate.mapping.Collection) AnnotationException(org.hibernate.AnnotationException) List(org.hibernate.mapping.List) IndexBackref(org.hibernate.mapping.IndexBackref) OneToMany(org.hibernate.mapping.OneToMany) SimpleValue(org.hibernate.mapping.SimpleValue) PersistentClass(org.hibernate.mapping.PersistentClass)

Example 12 with Collection

use of org.hibernate.mapping.Collection in project hibernate-orm by hibernate.

the class TableBinder method bindFk.

public static void bindFk(PersistentClass referencedEntity, PersistentClass destinationEntity, Ejb3JoinColumn[] columns, SimpleValue value, boolean unique, MetadataBuildingContext buildingContext) {
    PersistentClass associatedClass;
    if (destinationEntity != null) {
        //overridden destination
        associatedClass = destinationEntity;
    } else {
        associatedClass = columns[0].getPropertyHolder() == null ? null : columns[0].getPropertyHolder().getPersistentClass();
    }
    final String mappedByProperty = columns[0].getMappedBy();
    if (StringHelper.isNotEmpty(mappedByProperty)) {
        /**
			 * Get the columns of the mapped-by property
			 * copy them and link the copy to the actual value
			 */
        LOG.debugf("Retrieving property %s.%s", associatedClass.getEntityName(), mappedByProperty);
        final Property property = associatedClass.getRecursiveProperty(columns[0].getMappedBy());
        Iterator mappedByColumns;
        if (property.getValue() instanceof Collection) {
            Collection collection = ((Collection) property.getValue());
            Value element = collection.getElement();
            if (element == null) {
                throw new AnnotationException("Illegal use of mappedBy on both sides of the relationship: " + associatedClass.getEntityName() + "." + mappedByProperty);
            }
            mappedByColumns = element.getColumnIterator();
        } else {
            mappedByColumns = property.getValue().getColumnIterator();
        }
        while (mappedByColumns.hasNext()) {
            Column column = (Column) mappedByColumns.next();
            columns[0].overrideFromReferencedColumnIfNecessary(column);
            columns[0].linkValueUsingAColumnCopy(column, value);
        }
    } else if (columns[0].isImplicit()) {
        /**
			 * if columns are implicit, then create the columns based on the
			 * referenced entity id columns
			 */
        Iterator idColumns;
        if (referencedEntity instanceof JoinedSubclass) {
            idColumns = referencedEntity.getKey().getColumnIterator();
        } else {
            idColumns = referencedEntity.getIdentifier().getColumnIterator();
        }
        while (idColumns.hasNext()) {
            Column column = (Column) idColumns.next();
            columns[0].linkValueUsingDefaultColumnNaming(column, referencedEntity, value);
            columns[0].overrideFromReferencedColumnIfNecessary(column);
        }
    } else {
        int fkEnum = Ejb3JoinColumn.checkReferencedColumnsType(columns, referencedEntity, buildingContext);
        if (Ejb3JoinColumn.NON_PK_REFERENCE == fkEnum) {
            String referencedPropertyName;
            if (value instanceof ToOne) {
                referencedPropertyName = ((ToOne) value).getReferencedPropertyName();
            } else if (value instanceof DependantValue) {
                String propertyName = columns[0].getPropertyName();
                if (propertyName != null) {
                    Collection collection = (Collection) referencedEntity.getRecursiveProperty(propertyName).getValue();
                    referencedPropertyName = collection.getReferencedPropertyName();
                } else {
                    throw new AnnotationException("SecondaryTable JoinColumn cannot reference a non primary key");
                }
            } else {
                throw new AssertionFailure("Do a property ref on an unexpected Value type: " + value.getClass().getName());
            }
            if (referencedPropertyName == null) {
                throw new AssertionFailure("No property ref found while expected");
            }
            Property synthProp = referencedEntity.getReferencedProperty(referencedPropertyName);
            if (synthProp == null) {
                throw new AssertionFailure("Cannot find synthProp: " + referencedEntity.getEntityName() + "." + referencedPropertyName);
            }
            linkJoinColumnWithValueOverridingNameIfImplicit(referencedEntity, synthProp.getColumnIterator(), columns, value);
        } else {
            if (Ejb3JoinColumn.NO_REFERENCE == fkEnum) {
                //implicit case, we hope PK and FK columns are in the same order
                if (columns.length != referencedEntity.getIdentifier().getColumnSpan()) {
                    throw new AnnotationException("A Foreign key refering " + referencedEntity.getEntityName() + " from " + associatedClass.getEntityName() + " has the wrong number of column. should be " + referencedEntity.getIdentifier().getColumnSpan());
                }
                linkJoinColumnWithValueOverridingNameIfImplicit(referencedEntity, referencedEntity.getIdentifier().getColumnIterator(), columns, value);
            } else {
                //explicit referencedColumnName
                Iterator idColItr = referencedEntity.getKey().getColumnIterator();
                org.hibernate.mapping.Column col;
                //works cause the pk has to be on the primary table
                Table table = referencedEntity.getTable();
                if (!idColItr.hasNext()) {
                    LOG.debug("No column in the identifier!");
                }
                while (idColItr.hasNext()) {
                    boolean match = false;
                    //for each PK column, find the associated FK column.
                    col = (org.hibernate.mapping.Column) idColItr.next();
                    for (Ejb3JoinColumn joinCol : columns) {
                        String referencedColumn = joinCol.getReferencedColumn();
                        referencedColumn = buildingContext.getMetadataCollector().getPhysicalColumnName(table, referencedColumn);
                        //In JPA 2 referencedColumnName is case insensitive
                        if (referencedColumn.equalsIgnoreCase(col.getQuotedName(buildingContext.getMetadataCollector().getDatabase().getJdbcEnvironment().getDialect()))) {
                            //proper join column
                            if (joinCol.isNameDeferred()) {
                                joinCol.linkValueUsingDefaultColumnNaming(col, referencedEntity, value);
                            } else {
                                joinCol.linkWithValue(value);
                            }
                            joinCol.overrideFromReferencedColumnIfNecessary(col);
                            match = true;
                            break;
                        }
                    }
                    if (!match) {
                        throw new AnnotationException("Column name " + col.getName() + " of " + referencedEntity.getEntityName() + " not found in JoinColumns.referencedColumnName");
                    }
                }
            }
        }
    }
    value.createForeignKey();
    if (unique) {
        createUniqueConstraint(value);
    }
}
Also used : AssertionFailure(org.hibernate.AssertionFailure) Table(org.hibernate.mapping.Table) DependantValue(org.hibernate.mapping.DependantValue) Column(org.hibernate.mapping.Column) Ejb3JoinColumn(org.hibernate.cfg.Ejb3JoinColumn) Iterator(java.util.Iterator) SimpleValue(org.hibernate.mapping.SimpleValue) DependantValue(org.hibernate.mapping.DependantValue) Value(org.hibernate.mapping.Value) ToOne(org.hibernate.mapping.ToOne) Collection(org.hibernate.mapping.Collection) AnnotationException(org.hibernate.AnnotationException) Ejb3JoinColumn(org.hibernate.cfg.Ejb3JoinColumn) JoinedSubclass(org.hibernate.mapping.JoinedSubclass) Property(org.hibernate.mapping.Property) PersistentClass(org.hibernate.mapping.PersistentClass)

Example 13 with Collection

use of org.hibernate.mapping.Collection in project hibernate-orm by hibernate.

the class AttributeFactory method determineAttributeMetadata.

/**
	 * Here is most of the nuts and bolts of this factory, where we interpret the known JPA metadata
	 * against the known Hibernate metadata and build a descriptor for the attribute.
	 *
	 * @param attributeContext The attribute to be described
	 * @param memberResolver Strategy for how to resolve the member defining the attribute.
	 * @param <X> The owner type
	 * @param <Y> The attribute type
	 *
	 * @return The attribute description
	 */
@SuppressWarnings({ "unchecked" })
private <X, Y> AttributeMetadata<X, Y> determineAttributeMetadata(AttributeContext<X> attributeContext, MemberResolver memberResolver) {
    LOG.trace("Starting attribute metadata determination [" + attributeContext.getPropertyMapping().getName() + "]");
    final Member member = memberResolver.resolveMember(attributeContext);
    LOG.trace("    Determined member [" + member + "]");
    final Value value = attributeContext.getPropertyMapping().getValue();
    final org.hibernate.type.Type type = value.getType();
    LOG.trace("    Determined type [name=" + type.getName() + ", class=" + type.getClass().getName() + "]");
    if (type.isAnyType()) {
        // ANY mappings are currently not supported in the JPA metamodel; see HHH-6589
        if (context.isIgnoreUnsupported()) {
            return null;
        } else {
            throw new UnsupportedOperationException("ANY not supported");
        }
    } else if (type.isAssociationType()) {
        // collection or entity
        if (type.isEntityType()) {
            // entity
            return new SingularAttributeMetadataImpl<X, Y>(attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, determineSingularAssociationAttributeType(member));
        }
        // collection
        if (value instanceof Collection) {
            final Collection collValue = (Collection) value;
            final Value elementValue = collValue.getElement();
            final org.hibernate.type.Type elementType = elementValue.getType();
            // First, determine the type of the elements and use that to help determine the
            // collection type)
            final Attribute.PersistentAttributeType elementPersistentAttributeType;
            final Attribute.PersistentAttributeType persistentAttributeType;
            if (elementType.isAnyType()) {
                if (context.isIgnoreUnsupported()) {
                    return null;
                } else {
                    throw new UnsupportedOperationException("collection of any not supported yet");
                }
            }
            final boolean isManyToMany = isManyToMany(member);
            if (elementValue instanceof Component) {
                elementPersistentAttributeType = Attribute.PersistentAttributeType.EMBEDDED;
                persistentAttributeType = Attribute.PersistentAttributeType.ELEMENT_COLLECTION;
            } else if (elementType.isAssociationType()) {
                elementPersistentAttributeType = isManyToMany ? Attribute.PersistentAttributeType.MANY_TO_MANY : Attribute.PersistentAttributeType.ONE_TO_MANY;
                persistentAttributeType = elementPersistentAttributeType;
            } else {
                elementPersistentAttributeType = Attribute.PersistentAttributeType.BASIC;
                persistentAttributeType = Attribute.PersistentAttributeType.ELEMENT_COLLECTION;
            }
            final Attribute.PersistentAttributeType keyPersistentAttributeType;
            // Finally, we determine the type of the map key (if needed)
            if (value instanceof Map) {
                final Value keyValue = ((Map) value).getIndex();
                final org.hibernate.type.Type keyType = keyValue.getType();
                if (keyType.isAnyType()) {
                    if (context.isIgnoreUnsupported()) {
                        return null;
                    } else {
                        throw new UnsupportedOperationException("collection of any not supported yet");
                    }
                }
                if (keyValue instanceof Component) {
                    keyPersistentAttributeType = Attribute.PersistentAttributeType.EMBEDDED;
                } else if (keyType.isAssociationType()) {
                    keyPersistentAttributeType = Attribute.PersistentAttributeType.MANY_TO_ONE;
                } else {
                    keyPersistentAttributeType = Attribute.PersistentAttributeType.BASIC;
                }
            } else {
                keyPersistentAttributeType = null;
            }
            return new PluralAttributeMetadataImpl(attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, persistentAttributeType, elementPersistentAttributeType, keyPersistentAttributeType);
        } else if (value instanceof OneToMany) {
            // element value within a o.h.mapping.Collection (see logic branch above)
            throw new IllegalArgumentException("HUH???");
        //					final boolean isManyToMany = isManyToMany( member );
        //					//one to many with FK => entity
        //					return new PluralAttributeMetadataImpl(
        //							attributeContext.getPropertyMapping(),
        //							attributeContext.getOwnerType(),
        //							member,
        //							isManyToMany
        //									? Attribute.PersistentAttributeType.MANY_TO_MANY
        //									: Attribute.PersistentAttributeType.ONE_TO_MANY
        //							value,
        //							AttributeContext.TypeStatus.ENTITY,
        //							Attribute.PersistentAttributeType.ONE_TO_MANY,
        //							null, null, null
        //					);
        }
    } else if (attributeContext.getPropertyMapping().isComposite()) {
        // component
        return new SingularAttributeMetadataImpl<X, Y>(attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, Attribute.PersistentAttributeType.EMBEDDED);
    } else {
        // basic type
        return new SingularAttributeMetadataImpl<X, Y>(attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, Attribute.PersistentAttributeType.BASIC);
    }
    throw new UnsupportedOperationException("oops, we are missing something: " + attributeContext.getPropertyMapping());
}
Also used : OneToMany(org.hibernate.mapping.OneToMany) EmbeddedComponentType(org.hibernate.type.EmbeddedComponentType) EntityType(org.hibernate.type.EntityType) ComponentType(org.hibernate.type.ComponentType) Type(javax.persistence.metamodel.Type) ParameterizedType(java.lang.reflect.ParameterizedType) Value(org.hibernate.mapping.Value) Collection(org.hibernate.mapping.Collection) Component(org.hibernate.mapping.Component) Member(java.lang.reflect.Member) Map(org.hibernate.mapping.Map)

Example 14 with Collection

use of org.hibernate.mapping.Collection in project hibernate-orm by hibernate.

the class CollectionBinderTest method testAssociatedClassException.

@Test
@TestForIssue(jiraKey = "HHH-10106")
public void testAssociatedClassException() throws SQLException {
    final Collection collection = mock(Collection.class);
    final Map persistentClasses = mock(Map.class);
    final XClass collectionType = mock(XClass.class);
    final MetadataBuildingContext buildingContext = mock(MetadataBuildingContext.class);
    final InFlightMetadataCollector inFly = mock(InFlightMetadataCollector.class);
    final PersistentClass persistentClass = mock(PersistentClass.class);
    final Table table = mock(Table.class);
    when(buildingContext.getMetadataCollector()).thenReturn(inFly);
    when(persistentClasses.get(null)).thenReturn(null);
    when(collection.getOwner()).thenReturn(persistentClass);
    when(collectionType.getName()).thenReturn("List");
    when(persistentClass.getTable()).thenReturn(table);
    when(table.getName()).thenReturn("Hibernate");
    CollectionBinder collectionBinder = new CollectionBinder(false) {

        @Override
        protected Collection createCollection(PersistentClass persistentClass) {
            return null;
        }

        {
            final PropertyHolder propertyHolder = Mockito.mock(PropertyHolder.class);
            when(propertyHolder.getClassName()).thenReturn(CollectionBinderTest.class.getSimpleName());
            this.propertyName = "abc";
            this.propertyHolder = propertyHolder;
        }
    };
    String expectMessage = "Association [abc] for entity [CollectionBinderTest] references unmapped class [List]";
    try {
        collectionBinder.bindOneToManySecondPass(collection, persistentClasses, null, collectionType, false, false, buildingContext, null);
    } catch (MappingException e) {
        assertEquals(expectMessage, e.getMessage());
    }
}
Also used : InFlightMetadataCollector(org.hibernate.boot.spi.InFlightMetadataCollector) Table(org.hibernate.mapping.Table) PropertyHolder(org.hibernate.cfg.PropertyHolder) Collection(org.hibernate.mapping.Collection) MetadataBuildingContext(org.hibernate.boot.spi.MetadataBuildingContext) Map(java.util.Map) XClass(org.hibernate.annotations.common.reflection.XClass) PersistentClass(org.hibernate.mapping.PersistentClass) MappingException(org.hibernate.MappingException) Test(org.junit.Test) TestForIssue(org.hibernate.testing.TestForIssue)

Example 15 with Collection

use of org.hibernate.mapping.Collection in project hibernate-orm by hibernate.

the class DefaultNamingCollectionElementTest method checkDefaultCollectionTableName.

protected void checkDefaultCollectionTableName(Class<?> ownerEntityClass, String ownerCollectionPropertyName, String expectedCollectionTableName) {
    final org.hibernate.mapping.Collection collection = metadata().getCollectionBinding(ownerEntityClass.getName() + '.' + ownerCollectionPropertyName);
    final org.hibernate.mapping.Table table = collection.getCollectionTable();
    assertEquals(expectedCollectionTableName, table.getName());
}
Also used : Collection(org.hibernate.mapping.Collection)

Aggregations

Collection (org.hibernate.mapping.Collection)42 PersistentClass (org.hibernate.mapping.PersistentClass)19 Test (org.junit.Test)15 Property (org.hibernate.mapping.Property)11 Metadata (org.hibernate.boot.Metadata)9 MetadataSources (org.hibernate.boot.MetadataSources)9 Column (org.hibernate.mapping.Column)9 Iterator (java.util.Iterator)7 Component (org.hibernate.mapping.Component)7 RootClass (org.hibernate.mapping.RootClass)6 AnnotationException (org.hibernate.AnnotationException)5 SimpleValue (org.hibernate.mapping.SimpleValue)5 TestForIssue (org.hibernate.testing.TestForIssue)5 List (java.util.List)4 Map (java.util.Map)4 ElementCollection (javax.persistence.ElementCollection)4 StandardServiceRegistry (org.hibernate.boot.registry.StandardServiceRegistry)4 StandardServiceRegistryBuilder (org.hibernate.boot.registry.StandardServiceRegistryBuilder)4 Value (org.hibernate.mapping.Value)4 ArrayList (java.util.ArrayList)3