Search in sources :

Example 71 with PersistentClass

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

the class InFlightMetadataCollectorImpl method processExportableProducers.

private void processExportableProducers() {
    // for now we only handle id generators as ExportableProducers
    final Dialect dialect = getDatabase().getJdbcEnvironment().getDialect();
    final String defaultCatalog = extractName(getDatabase().getDefaultNamespace().getName().getCatalog(), dialect);
    final String defaultSchema = extractName(getDatabase().getDefaultNamespace().getName().getSchema(), dialect);
    for (PersistentClass entityBinding : entityBindingMap.values()) {
        if (entityBinding.isInherited()) {
            continue;
        }
        handleIdentifierValueBinding(entityBinding.getIdentifier(), dialect, defaultCatalog, defaultSchema, (RootClass) entityBinding);
    }
    for (Collection collection : collectionBindingMap.values()) {
        if (!IdentifierCollection.class.isInstance(collection)) {
            continue;
        }
        handleIdentifierValueBinding(((IdentifierCollection) collection).getIdentifier(), dialect, defaultCatalog, defaultSchema, null);
    }
}
Also used : Dialect(org.hibernate.dialect.Dialect) Collection(org.hibernate.mapping.Collection) IdentifierCollection(org.hibernate.mapping.IdentifierCollection) PersistentClass(org.hibernate.mapping.PersistentClass) IdentifierCollection(org.hibernate.mapping.IdentifierCollection)

Example 72 with PersistentClass

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

the class AnnotationBinder method bindIdClass.

private static void bindIdClass(String generatorType, String generatorName, PropertyData inferredData, PropertyData baseInferredData, Ejb3Column[] columns, PropertyHolder propertyHolder, boolean isComposite, AccessType propertyAccessor, EntityBinder entityBinder, boolean isEmbedded, boolean isIdentifierMapper, MetadataBuildingContext buildingContext, Map<XClass, InheritanceState> inheritanceStatePerClass) {
    /*
		 * Fill simple value and property since and Id is a property
		 */
    PersistentClass persistentClass = propertyHolder.getPersistentClass();
    if (!(persistentClass instanceof RootClass)) {
        throw new AnnotationException("Unable to define/override @Id(s) on a subclass: " + propertyHolder.getEntityName());
    }
    RootClass rootClass = (RootClass) persistentClass;
    String persistentClassName = rootClass.getClassName();
    SimpleValue id;
    final String propertyName = inferredData.getPropertyName();
    if (isComposite) {
        id = fillComponent(propertyHolder, inferredData, baseInferredData, propertyAccessor, false, entityBinder, isEmbedded, isIdentifierMapper, false, buildingContext, inheritanceStatePerClass);
        Component componentId = (Component) id;
        componentId.setKey(true);
        if (rootClass.getIdentifier() != null) {
            throw new AnnotationException(componentId.getComponentClassName() + " must not have @Id properties when used as an @EmbeddedId");
        }
        if (componentId.getPropertySpan() == 0) {
            throw new AnnotationException(componentId.getComponentClassName() + " has no persistent id property");
        }
        // tuplizers
        XProperty property = inferredData.getProperty();
        setupComponentTuplizer(property, componentId);
    } else {
        for (Ejb3Column column : columns) {
            // this is an id
            column.forceNotNull();
        }
        SimpleValueBinder value = new SimpleValueBinder();
        value.setPropertyName(propertyName);
        value.setReturnedClassName(inferredData.getTypeName());
        value.setColumns(columns);
        value.setPersistentClassName(persistentClassName);
        value.setBuildingContext(buildingContext);
        value.setType(inferredData.getProperty(), inferredData.getClassOrElement(), persistentClassName, null);
        value.setAccessType(propertyAccessor);
        id = value.make();
    }
    rootClass.setIdentifier(id);
    SecondPass secondPass = new IdGeneratorResolverSecondPass(id, inferredData.getProperty(), generatorType, generatorName, buildingContext);
    buildingContext.getMetadataCollector().addSecondPass(secondPass);
    if (isEmbedded) {
        rootClass.setEmbeddedIdentifier(inferredData.getPropertyClass() == null);
    } else {
        PropertyBinder binder = new PropertyBinder();
        binder.setName(propertyName);
        binder.setValue(id);
        binder.setAccessType(inferredData.getDefaultAccess());
        binder.setProperty(inferredData.getProperty());
        Property prop = binder.makeProperty();
        rootClass.setIdentifierProperty(prop);
        // if the id property is on a superclass, update the metamodel
        final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(inferredData.getDeclaringClass(), inheritanceStatePerClass, buildingContext);
        if (superclass != null) {
            superclass.setDeclaredIdentifierProperty(prop);
        } else {
            // we know the property is on the actual entity
            rootClass.setDeclaredIdentifierProperty(prop);
        }
    }
}
Also used : RootClass(org.hibernate.mapping.RootClass) XProperty(org.hibernate.annotations.common.reflection.XProperty) SimpleValue(org.hibernate.mapping.SimpleValue) SimpleValueBinder(org.hibernate.cfg.annotations.SimpleValueBinder) AnnotationException(org.hibernate.AnnotationException) PropertyBinder(org.hibernate.cfg.annotations.PropertyBinder) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty) PersistentClass(org.hibernate.mapping.PersistentClass)

Example 73 with PersistentClass

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

the class AnnotationBinder method bindClass.

/**
 * Bind a class having JSR175 annotations. Subclasses <b>have to</b> be bound after its parent class.
 *
 * @param clazzToProcess entity to bind as {@code XClass} instance
 * @param inheritanceStatePerClass Meta data about the inheritance relationships for all mapped classes
 *
 * @throws MappingException in case there is a configuration error
 */
public static void bindClass(XClass clazzToProcess, Map<XClass, InheritanceState> inheritanceStatePerClass, MetadataBuildingContext context) throws MappingException {
    // @Entity and @MappedSuperclass on the same class leads to a NPE down the road
    if (clazzToProcess.isAnnotationPresent(Entity.class) && clazzToProcess.isAnnotationPresent(MappedSuperclass.class)) {
        throw new AnnotationException("An entity cannot be annotated with both @Entity and @MappedSuperclass: " + clazzToProcess.getName());
    }
    // TODO: be more strict with secondarytable allowance (not for ids, not for secondary table join columns etc)
    InheritanceState inheritanceState = inheritanceStatePerClass.get(clazzToProcess);
    AnnotatedClassType classType = context.getMetadataCollector().getClassType(clazzToProcess);
    // Queries declared in MappedSuperclass should be usable in Subclasses
    if (AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals(classType)) {
        bindQueries(clazzToProcess, context);
        bindTypeDefs(clazzToProcess, context);
        bindFilterDefs(clazzToProcess, context);
    }
    if (!isEntityClassType(clazzToProcess, classType)) {
        return;
    }
    if (LOG.isDebugEnabled()) {
        LOG.debugf("Binding entity from annotated class: %s", clazzToProcess.getName());
    }
    PersistentClass superEntity = getSuperEntity(clazzToProcess, inheritanceStatePerClass, context, inheritanceState);
    PersistentClass persistentClass = makePersistentClass(inheritanceState, superEntity, context);
    Entity entityAnn = clazzToProcess.getAnnotation(Entity.class);
    org.hibernate.annotations.Entity hibEntityAnn = clazzToProcess.getAnnotation(org.hibernate.annotations.Entity.class);
    EntityBinder entityBinder = new EntityBinder(entityAnn, hibEntityAnn, clazzToProcess, persistentClass, context);
    entityBinder.setInheritanceState(inheritanceState);
    bindQueries(clazzToProcess, context);
    bindFilterDefs(clazzToProcess, context);
    bindTypeDefs(clazzToProcess, context);
    bindFetchProfiles(clazzToProcess, context);
    BinderHelper.bindAnyMetaDefs(clazzToProcess, context);
    String schema = "";
    // might be no @Table annotation on the annotated class
    String table = "";
    String catalog = "";
    List<UniqueConstraintHolder> uniqueConstraints = new ArrayList<>();
    javax.persistence.Table tabAnn = null;
    if (clazzToProcess.isAnnotationPresent(javax.persistence.Table.class)) {
        tabAnn = clazzToProcess.getAnnotation(javax.persistence.Table.class);
        table = tabAnn.name();
        schema = tabAnn.schema();
        catalog = tabAnn.catalog();
        uniqueConstraints = TableBinder.buildUniqueConstraintHolders(tabAnn.uniqueConstraints());
    }
    Ejb3JoinColumn[] inheritanceJoinedColumns = makeInheritanceJoinColumns(clazzToProcess, context, inheritanceState, superEntity);
    final Ejb3DiscriminatorColumn discriminatorColumn;
    if (InheritanceType.SINGLE_TABLE.equals(inheritanceState.getType())) {
        discriminatorColumn = processSingleTableDiscriminatorProperties(clazzToProcess, context, inheritanceState, entityBinder);
    } else if (InheritanceType.JOINED.equals(inheritanceState.getType())) {
        discriminatorColumn = processJoinedDiscriminatorProperties(clazzToProcess, context, inheritanceState, entityBinder);
    } else {
        discriminatorColumn = null;
    }
    entityBinder.setProxy(clazzToProcess.getAnnotation(Proxy.class));
    entityBinder.setBatchSize(clazzToProcess.getAnnotation(BatchSize.class));
    entityBinder.setWhere(clazzToProcess.getAnnotation(Where.class));
    applyCacheSettings(entityBinder, clazzToProcess, context);
    bindFilters(clazzToProcess, entityBinder, context);
    entityBinder.bindEntity();
    if (inheritanceState.hasTable()) {
        Check checkAnn = clazzToProcess.getAnnotation(Check.class);
        String constraints = checkAnn == null ? null : checkAnn.constraints();
        EntityTableXref denormalizedTableXref = inheritanceState.hasDenormalizedTable() ? context.getMetadataCollector().getEntityTableXref(superEntity.getEntityName()) : null;
        entityBinder.bindTable(schema, catalog, table, uniqueConstraints, constraints, denormalizedTableXref);
    } else {
        if (clazzToProcess.isAnnotationPresent(Table.class)) {
            LOG.invalidTableAnnotation(clazzToProcess.getName());
        }
        if (inheritanceState.getType() == InheritanceType.SINGLE_TABLE) {
            // we at least need to properly set up the EntityTableXref
            entityBinder.bindTableForDiscriminatedSubclass(context.getMetadataCollector().getEntityTableXref(superEntity.getEntityName()));
        }
    }
    PropertyHolder propertyHolder = PropertyHolderBuilder.buildPropertyHolder(clazzToProcess, persistentClass, entityBinder, context, inheritanceStatePerClass);
    javax.persistence.SecondaryTable secTabAnn = clazzToProcess.getAnnotation(javax.persistence.SecondaryTable.class);
    javax.persistence.SecondaryTables secTabsAnn = clazzToProcess.getAnnotation(javax.persistence.SecondaryTables.class);
    entityBinder.firstLevelSecondaryTablesBinding(secTabAnn, secTabsAnn);
    OnDelete onDeleteAnn = clazzToProcess.getAnnotation(OnDelete.class);
    boolean onDeleteAppropriate = false;
    // todo : sucks that this is separate from RootClass distinction
    final boolean isInheritanceRoot = !inheritanceState.hasParents();
    final boolean hasSubclasses = inheritanceState.hasSiblings();
    if (InheritanceType.JOINED.equals(inheritanceState.getType())) {
        if (inheritanceState.hasParents()) {
            onDeleteAppropriate = true;
            final JoinedSubclass jsc = (JoinedSubclass) persistentClass;
            SimpleValue key = new DependantValue(context, jsc.getTable(), jsc.getIdentifier());
            jsc.setKey(key);
            ForeignKey fk = clazzToProcess.getAnnotation(ForeignKey.class);
            if (fk != null && !BinderHelper.isEmptyAnnotationValue(fk.name())) {
                key.setForeignKeyName(fk.name());
            } else {
                final PrimaryKeyJoinColumn pkJoinColumn = clazzToProcess.getAnnotation(PrimaryKeyJoinColumn.class);
                final PrimaryKeyJoinColumns pkJoinColumns = clazzToProcess.getAnnotation(PrimaryKeyJoinColumns.class);
                if (pkJoinColumns != null && pkJoinColumns.foreignKey().value() == ConstraintMode.NO_CONSTRAINT) {
                    // don't apply a constraint based on ConstraintMode
                    key.setForeignKeyName("none");
                } else if (pkJoinColumns != null && !StringHelper.isEmpty(pkJoinColumns.foreignKey().name())) {
                    key.setForeignKeyName(pkJoinColumns.foreignKey().name());
                } else if (pkJoinColumn != null && pkJoinColumn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT) {
                    // don't apply a constraint based on ConstraintMode
                    key.setForeignKeyName("none");
                } else if (pkJoinColumn != null && !StringHelper.isEmpty(pkJoinColumn.foreignKey().name())) {
                    key.setForeignKeyName(pkJoinColumn.foreignKey().name());
                }
            }
            if (onDeleteAnn != null) {
                key.setCascadeDeleteEnabled(OnDeleteAction.CASCADE.equals(onDeleteAnn.action()));
            } else {
                key.setCascadeDeleteEnabled(false);
            }
            // we are never in a second pass at that stage, so queue it
            context.getMetadataCollector().addSecondPass(new JoinedSubclassFkSecondPass(jsc, inheritanceJoinedColumns, key, context));
            context.getMetadataCollector().addSecondPass(new CreateKeySecondPass(jsc));
        }
        if (isInheritanceRoot) {
            // (it is perfectly valid for joined subclasses to not have discriminators).
            if (discriminatorColumn != null) {
                // we have a discriminator column
                if (hasSubclasses || !discriminatorColumn.isImplicit()) {
                    bindDiscriminatorColumnToRootPersistentClass((RootClass) persistentClass, discriminatorColumn, entityBinder.getSecondaryTables(), propertyHolder, context);
                    // bind it again since the type might have changed
                    entityBinder.bindDiscriminatorValue();
                }
            }
        }
    } else if (InheritanceType.SINGLE_TABLE.equals(inheritanceState.getType())) {
        if (isInheritanceRoot) {
            if (hasSubclasses || !discriminatorColumn.isImplicit()) {
                bindDiscriminatorColumnToRootPersistentClass((RootClass) persistentClass, discriminatorColumn, entityBinder.getSecondaryTables(), propertyHolder, context);
                // bind it again since the type might have changed
                entityBinder.bindDiscriminatorValue();
            }
        }
    }
    if (onDeleteAnn != null && !onDeleteAppropriate) {
        LOG.invalidOnDeleteAnnotation(propertyHolder.getEntityName());
    }
    // try to find class level generators
    HashMap<String, IdentifierGeneratorDefinition> classGenerators = buildGenerators(clazzToProcess, context);
    // check properties
    final InheritanceState.ElementsToProcess elementsToProcess = inheritanceState.getElementsToProcess();
    inheritanceState.postProcess(persistentClass, entityBinder);
    final boolean subclassAndSingleTableStrategy = inheritanceState.getType() == InheritanceType.SINGLE_TABLE && inheritanceState.hasParents();
    Set<String> idPropertiesIfIdClass = new HashSet<>();
    boolean isIdClass = mapAsIdClass(inheritanceStatePerClass, inheritanceState, persistentClass, entityBinder, propertyHolder, elementsToProcess, idPropertiesIfIdClass, context);
    if (!isIdClass) {
        entityBinder.setWrapIdsInEmbeddedComponents(elementsToProcess.getIdPropertyCount() > 1);
    }
    processIdPropertiesIfNotAlready(inheritanceStatePerClass, context, persistentClass, entityBinder, propertyHolder, classGenerators, elementsToProcess, subclassAndSingleTableStrategy, idPropertiesIfIdClass);
    if (!inheritanceState.hasParents()) {
        final RootClass rootClass = (RootClass) persistentClass;
        context.getMetadataCollector().addSecondPass(new CreateKeySecondPass(rootClass));
    } else {
        superEntity.addSubclass((Subclass) persistentClass);
    }
    context.getMetadataCollector().addEntityBinding(persistentClass);
    // Process secondary tables and complementary definitions (ie o.h.a.Table)
    context.getMetadataCollector().addSecondPass(new SecondaryTableSecondPass(entityBinder, propertyHolder, clazzToProcess));
    // add process complementary Table definition (index & all)
    entityBinder.processComplementaryTableDefinitions(clazzToProcess.getAnnotation(org.hibernate.annotations.Table.class));
    entityBinder.processComplementaryTableDefinitions(clazzToProcess.getAnnotation(org.hibernate.annotations.Tables.class));
    entityBinder.processComplementaryTableDefinitions(tabAnn);
}
Also used : Entity(javax.persistence.Entity) ArrayList(java.util.ArrayList) Check(org.hibernate.annotations.Check) Proxy(org.hibernate.annotations.Proxy) PrimaryKeyJoinColumn(javax.persistence.PrimaryKeyJoinColumn) Table(javax.persistence.Table) PrimaryKeyJoinColumns(javax.persistence.PrimaryKeyJoinColumns) AnnotationException(org.hibernate.AnnotationException) JoinedSubclass(org.hibernate.mapping.JoinedSubclass) PersistentClass(org.hibernate.mapping.PersistentClass) HashSet(java.util.HashSet) RootClass(org.hibernate.mapping.RootClass) BatchSize(org.hibernate.annotations.BatchSize) Table(javax.persistence.Table) CollectionTable(javax.persistence.CollectionTable) JoinTable(javax.persistence.JoinTable) DependantValue(org.hibernate.mapping.DependantValue) ForeignKey(org.hibernate.annotations.ForeignKey) SimpleValue(org.hibernate.mapping.SimpleValue) MappedSuperclass(javax.persistence.MappedSuperclass) EntityTableXref(org.hibernate.boot.spi.InFlightMetadataCollector.EntityTableXref) IdentifierGeneratorDefinition(org.hibernate.boot.model.IdentifierGeneratorDefinition) EntityBinder(org.hibernate.cfg.annotations.EntityBinder) Where(org.hibernate.annotations.Where) OnDelete(org.hibernate.annotations.OnDelete)

Example 74 with PersistentClass

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

the class UnionSubclassEntityPersister method generateSubquery.

protected String generateSubquery(PersistentClass model, Mapping mapping) {
    Dialect dialect = getFactory().getDialect();
    Settings settings = getFactory().getSettings();
    if (!model.hasSubclasses()) {
        return model.getTable().getQualifiedName(dialect, settings.getDefaultCatalogName(), settings.getDefaultSchemaName());
    }
    HashSet columns = new LinkedHashSet();
    Iterator titer = model.getSubclassTableClosureIterator();
    while (titer.hasNext()) {
        Table table = (Table) titer.next();
        if (!table.isAbstractUnionTable()) {
            Iterator citer = table.getColumnIterator();
            while (citer.hasNext()) {
                columns.add(citer.next());
            }
        }
    }
    StringBuilder buf = new StringBuilder().append("( ");
    Iterator siter = new JoinedIterator(new SingletonIterator(model), model.getSubclassIterator());
    while (siter.hasNext()) {
        PersistentClass clazz = (PersistentClass) siter.next();
        Table table = clazz.getTable();
        if (!table.isAbstractUnionTable()) {
            // TODO: move to .sql package!!
            buf.append("select ");
            Iterator citer = columns.iterator();
            while (citer.hasNext()) {
                Column col = (Column) citer.next();
                if (!table.containsColumn(col)) {
                    int sqlType = col.getSqlTypeCode(mapping);
                    buf.append(dialect.getSelectClauseNullString(sqlType)).append(" as ");
                }
                buf.append(col.getQuotedName(dialect));
                buf.append(", ");
            }
            buf.append(clazz.getSubclassId()).append(" as clazz_");
            buf.append(" from ").append(table.getQualifiedName(dialect, settings.getDefaultCatalogName(), settings.getDefaultSchemaName()));
            buf.append(" union ");
            if (dialect.supportsUnionAll()) {
                buf.append("all ");
            }
        }
    }
    if (buf.length() > 2) {
        // chop the last union (all)
        buf.setLength(buf.length() - (dialect.supportsUnionAll() ? 11 : 7));
    }
    return buf.append(" )").toString();
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Table(org.hibernate.mapping.Table) Column(org.hibernate.mapping.Column) SingletonIterator(org.hibernate.internal.util.collections.SingletonIterator) Dialect(org.hibernate.dialect.Dialect) JoinedIterator(org.hibernate.internal.util.collections.JoinedIterator) Iterator(java.util.Iterator) SingletonIterator(org.hibernate.internal.util.collections.SingletonIterator) Settings(org.hibernate.cfg.Settings) JoinedIterator(org.hibernate.internal.util.collections.JoinedIterator) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) PersistentClass(org.hibernate.mapping.PersistentClass)

Example 75 with PersistentClass

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

the class MetamodelImpl method buildMappedSuperclassType.

// TODO remove / reduce @SW scope
@SuppressWarnings("unchecked")
private static MappedSuperclassTypeImpl<?> buildMappedSuperclassType(MappedSuperclass mappedSuperclass, MetadataContext context) {
    final MappedSuperclass superMappedSuperclass = mappedSuperclass.getSuperMappedSuperclass();
    AbstractIdentifiableType<?> superType = superMappedSuperclass == null ? null : locateOrBuildMappedsuperclassType(superMappedSuperclass, context);
    // no mappedSuperclass, check for a super entity
    if (superType == null) {
        final PersistentClass superPersistentClass = mappedSuperclass.getSuperPersistentClass();
        superType = superPersistentClass == null ? null : locateOrBuildEntityType(superPersistentClass, context);
    }
    final Class javaType = mappedSuperclass.getMappedClass();
    MappedSuperclassTypeImpl mappedSuperclassType = new MappedSuperclassTypeImpl(javaType, mappedSuperclass, superType);
    context.registerMappedSuperclassType(mappedSuperclass, mappedSuperclassType);
    return mappedSuperclassType;
}
Also used : MappedSuperclass(org.hibernate.mapping.MappedSuperclass) PersistentClass(org.hibernate.mapping.PersistentClass) RootClass(org.hibernate.mapping.RootClass) PersistentClass(org.hibernate.mapping.PersistentClass)

Aggregations

PersistentClass (org.hibernate.mapping.PersistentClass)229 Test (org.junit.Test)121 Property (org.hibernate.mapping.Property)65 MetadataSources (org.hibernate.boot.MetadataSources)53 IPersistentClass (org.jboss.tools.hibernate.runtime.spi.IPersistentClass)52 RootClass (org.hibernate.mapping.RootClass)50 Metadata (org.hibernate.boot.Metadata)45 Column (org.hibernate.mapping.Column)43 StandardServiceRegistryBuilder (org.hibernate.boot.registry.StandardServiceRegistryBuilder)42 StandardServiceRegistry (org.hibernate.boot.registry.StandardServiceRegistry)38 Iterator (java.util.Iterator)30 SimpleValue (org.hibernate.mapping.SimpleValue)24 HashMap (java.util.HashMap)22 Collection (org.hibernate.mapping.Collection)21 MappingException (org.hibernate.MappingException)20 MetadataImplementor (org.hibernate.boot.spi.MetadataImplementor)20 Table (org.hibernate.mapping.Table)20 Map (java.util.Map)19 ArrayList (java.util.ArrayList)18 TestForIssue (org.hibernate.testing.TestForIssue)18