Search in sources :

Example 1 with SecondPass

use of org.hibernate.cfg.SecondPass in project hibernate-orm by hibernate.

the class NamedQueryBinder method processNamedNativeQuery.

public static void processNamedNativeQuery(final HbmLocalMetadataBuildingContext context, JaxbHbmNamedNativeQueryType namedQueryBinding, String prefix) {
    final String queryName = prefix + namedQueryBinding.getName();
    final NamedSQLQueryDefinitionBuilder builder = new NamedSQLQueryDefinitionBuilder().setName(queryName).setComment(namedQueryBinding.getComment()).setCacheable(namedQueryBinding.isCacheable()).setCacheMode(namedQueryBinding.getCacheMode()).setCacheRegion(namedQueryBinding.getCacheRegion()).setTimeout(namedQueryBinding.getTimeout()).setReadOnly(namedQueryBinding.isReadOnly()).setFlushMode(namedQueryBinding.getFlushMode()).setFetchSize(namedQueryBinding.getFetchSize()).setCallable(namedQueryBinding.isCallable()).setResultSetRef(namedQueryBinding.getResultsetRef());
    final ImplicitResultSetMappingDefinition.Builder implicitResultSetMappingBuilder = new ImplicitResultSetMappingDefinition.Builder(queryName);
    boolean foundQuery = false;
    for (Object content : namedQueryBinding.getContent()) {
        final boolean wasQuery = processNamedQueryContentItem(content, builder, implicitResultSetMappingBuilder, namedQueryBinding, context);
        if (wasQuery) {
            foundQuery = true;
        }
    }
    if (!foundQuery) {
        throw new org.hibernate.boot.MappingException(String.format("Named native query [%s] did not specify query string", namedQueryBinding.getName()), context.getOrigin());
    }
    if (implicitResultSetMappingBuilder.hasAnyReturns()) {
        if (StringHelper.isNotEmpty(namedQueryBinding.getResultsetRef())) {
            throw new org.hibernate.boot.MappingException(String.format("Named native query [%s] specified both a resultset-ref and an inline mapping of results", namedQueryBinding.getName()), context.getOrigin());
        }
        // Building a ResultSet mapping needs access to entity bindings for any entity
        // returns it defines.  But binding for those entities may have not been
        // completed yet.  For "normal" ResultSet mappings, this is already handled by
        // the fact that MetadataSourceProcessor#processResultSetMappings() is called
        // after all entity hierarchies have been processed.  However, here we are in
        // the middle of processing named-queries (either top-level or entity-level)
        // and have no guarantee that any entity bindings we may need here are bound.
        // So we add the second-pass to bind the implicit resultSet mapping.
        // 
        // It is possible to know here whether the second-pass is needed or whether we
        // can immediately bind the ResultSet mapping.
        // todo : consider implementing this (^^) checking
        final ImplicitResultSetMappingDefinition implicitResultSetMappingDefinition = implicitResultSetMappingBuilder.build();
        builder.setResultSetRef(implicitResultSetMappingDefinition.getName());
        context.getMetadataCollector().addSecondPass(new SecondPass() {

            @Override
            public void doSecondPass(Map persistentClasses) throws MappingException {
                final ResultSetMappingDefinition resultSetMappingDefinition = ResultSetMappingBinder.bind(implicitResultSetMappingDefinition, context);
                context.getMetadataCollector().addResultSetMapping(resultSetMappingDefinition);
                NativeSQLQueryReturn[] newQueryReturns = resultSetMappingDefinition.getQueryReturns();
                final NamedSQLQueryDefinition queryDefinition = context.getMetadataCollector().getNamedNativeQueryDefinition(queryName);
                if (queryDefinition != null) {
                    queryDefinition.addQueryReturns(newQueryReturns);
                }
            }
        });
    }
    context.getMetadataCollector().addNamedNativeQuery(builder.createNamedQueryDefinition());
}
Also used : NamedQueryDefinitionBuilder(org.hibernate.engine.spi.NamedQueryDefinitionBuilder) NamedSQLQueryDefinitionBuilder(org.hibernate.engine.spi.NamedSQLQueryDefinitionBuilder) ImplicitResultSetMappingDefinition(org.hibernate.boot.jaxb.hbm.internal.ImplicitResultSetMappingDefinition) MappingException(org.hibernate.MappingException) NamedSQLQueryDefinition(org.hibernate.engine.spi.NamedSQLQueryDefinition) SecondPass(org.hibernate.cfg.SecondPass) HashMap(java.util.HashMap) Map(java.util.Map) NamedSQLQueryDefinitionBuilder(org.hibernate.engine.spi.NamedSQLQueryDefinitionBuilder) ResultSetMappingDefinition(org.hibernate.engine.ResultSetMappingDefinition) ImplicitResultSetMappingDefinition(org.hibernate.boot.jaxb.hbm.internal.ImplicitResultSetMappingDefinition)

Example 2 with SecondPass

use of org.hibernate.cfg.SecondPass in project hibernate-orm by hibernate.

the class CollectionBinder method bind.

public void bind() {
    this.collection = createCollection(propertyHolder.getPersistentClass());
    String role = StringHelper.qualify(propertyHolder.getPath(), propertyName);
    LOG.debugf("Collection role: %s", role);
    collection.setRole(role);
    collection.setMappedByProperty(mappedBy);
    if (property.isAnnotationPresent(MapKeyColumn.class) && mapKeyPropertyName != null) {
        throw new AnnotationException("Cannot mix @javax.persistence.MapKey and @MapKeyColumn or @org.hibernate.annotations.MapKey " + "on the same collection: " + StringHelper.qualify(propertyHolder.getPath(), propertyName));
    }
    // set explicit type information
    if (explicitType != null) {
        final TypeDefinition typeDef = buildingContext.getMetadataCollector().getTypeDefinition(explicitType);
        if (typeDef == null) {
            collection.setTypeName(explicitType);
            collection.setTypeParameters(explicitTypeParameters);
        } else {
            collection.setTypeName(typeDef.getTypeImplementorClass().getName());
            collection.setTypeParameters(typeDef.getParameters());
        }
    }
    // set laziness
    defineFetchingStrategy();
    collection.setBatchSize(batchSize);
    collection.setMutable(!property.isAnnotationPresent(Immutable.class));
    // work on association
    boolean isMappedBy = !BinderHelper.isEmptyAnnotationValue(mappedBy);
    final OptimisticLock lockAnn = property.getAnnotation(OptimisticLock.class);
    final boolean includeInOptimisticLockChecks = (lockAnn != null) ? !lockAnn.excluded() : !isMappedBy;
    collection.setOptimisticLocked(includeInOptimisticLockChecks);
    Persister persisterAnn = property.getAnnotation(Persister.class);
    if (persisterAnn != null) {
        collection.setCollectionPersisterClass(persisterAnn.impl());
    }
    applySortingAndOrdering(collection);
    // set cache
    if (StringHelper.isNotEmpty(cacheConcurrencyStrategy)) {
        collection.setCacheConcurrencyStrategy(cacheConcurrencyStrategy);
        collection.setCacheRegionName(cacheRegionName);
    }
    // SQL overriding
    SQLInsert sqlInsert = property.getAnnotation(SQLInsert.class);
    SQLUpdate sqlUpdate = property.getAnnotation(SQLUpdate.class);
    SQLDelete sqlDelete = property.getAnnotation(SQLDelete.class);
    SQLDeleteAll sqlDeleteAll = property.getAnnotation(SQLDeleteAll.class);
    Loader loader = property.getAnnotation(Loader.class);
    if (sqlInsert != null) {
        collection.setCustomSQLInsert(sqlInsert.sql().trim(), sqlInsert.callable(), ExecuteUpdateResultCheckStyle.fromExternalName(sqlInsert.check().toString().toLowerCase(Locale.ROOT)));
    }
    if (sqlUpdate != null) {
        collection.setCustomSQLUpdate(sqlUpdate.sql(), sqlUpdate.callable(), ExecuteUpdateResultCheckStyle.fromExternalName(sqlUpdate.check().toString().toLowerCase(Locale.ROOT)));
    }
    if (sqlDelete != null) {
        collection.setCustomSQLDelete(sqlDelete.sql(), sqlDelete.callable(), ExecuteUpdateResultCheckStyle.fromExternalName(sqlDelete.check().toString().toLowerCase(Locale.ROOT)));
    }
    if (sqlDeleteAll != null) {
        collection.setCustomSQLDeleteAll(sqlDeleteAll.sql(), sqlDeleteAll.callable(), ExecuteUpdateResultCheckStyle.fromExternalName(sqlDeleteAll.check().toString().toLowerCase(Locale.ROOT)));
    }
    if (loader != null) {
        collection.setLoaderName(loader.namedQuery());
    }
    if (isMappedBy && (property.isAnnotationPresent(JoinColumn.class) || property.isAnnotationPresent(JoinColumns.class) || propertyHolder.getJoinTable(property) != null)) {
        String message = "Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn: ";
        message += StringHelper.qualify(propertyHolder.getPath(), propertyName);
        throw new AnnotationException(message);
    }
    if (!isMappedBy && oneToMany && property.isAnnotationPresent(OnDelete.class) && !property.isAnnotationPresent(JoinColumn.class)) {
        String message = "Unidirectional one-to-many associations annotated with @OnDelete must define @JoinColumn: ";
        message += StringHelper.qualify(propertyHolder.getPath(), propertyName);
        throw new AnnotationException(message);
    }
    collection.setInverse(isMappedBy);
    // many to many may need some second pass informations
    if (!oneToMany && isMappedBy) {
        buildingContext.getMetadataCollector().addMappedBy(getCollectionType().getName(), mappedBy, propertyName);
    }
    // TODO reducce tableBinder != null and oneToMany
    XClass collectionType = getCollectionType();
    if (inheritanceStatePerClass == null)
        throw new AssertionFailure("inheritanceStatePerClass not set");
    SecondPass sp = getSecondPass(fkJoinColumns, joinColumns, inverseJoinColumns, elementColumns, mapKeyColumns, mapKeyManyToManyColumns, isEmbedded, property, collectionType, ignoreNotFound, oneToMany, tableBinder, buildingContext);
    if (collectionType.isAnnotationPresent(Embeddable.class) || // JPA 2
    property.isAnnotationPresent(ElementCollection.class)) {
        // do it right away, otherwise @ManyToOne on composite element call addSecondPass
        // and raise a ConcurrentModificationException
        // sp.doSecondPass( CollectionHelper.EMPTY_MAP );
        buildingContext.getMetadataCollector().addSecondPass(sp, !isMappedBy);
    } else {
        buildingContext.getMetadataCollector().addSecondPass(sp, !isMappedBy);
    }
    buildingContext.getMetadataCollector().addCollectionBinding(collection);
    // property building
    PropertyBinder binder = new PropertyBinder();
    binder.setName(propertyName);
    binder.setValue(collection);
    binder.setCascade(cascadeStrategy);
    if (cascadeStrategy != null && cascadeStrategy.contains("delete-orphan")) {
        collection.setOrphanDelete(true);
    }
    binder.setLazy(collection.isLazy());
    final LazyGroup lazyGroupAnnotation = property.getAnnotation(LazyGroup.class);
    if (lazyGroupAnnotation != null) {
        binder.setLazyGroup(lazyGroupAnnotation.value());
    }
    binder.setAccessType(accessType);
    binder.setProperty(property);
    binder.setInsertable(insertable);
    binder.setUpdatable(updatable);
    Property prop = binder.makeProperty();
    // we don't care about the join stuffs because the column is on the association table.
    if (!declaringClassSet)
        throw new AssertionFailure("DeclaringClass is not set in CollectionBinder while binding");
    propertyHolder.addProperty(prop, declaringClass);
}
Also used : AssertionFailure(org.hibernate.annotations.common.AssertionFailure) MapKeyColumn(javax.persistence.MapKeyColumn) Loader(org.hibernate.annotations.Loader) SQLDelete(org.hibernate.annotations.SQLDelete) XClass(org.hibernate.annotations.common.reflection.XClass) TypeDefinition(org.hibernate.boot.model.TypeDefinition) Embeddable(javax.persistence.Embeddable) SecondPass(org.hibernate.cfg.SecondPass) CollectionSecondPass(org.hibernate.cfg.CollectionSecondPass) LazyGroup(org.hibernate.annotations.LazyGroup) AnnotationException(org.hibernate.AnnotationException) SQLInsert(org.hibernate.annotations.SQLInsert) SQLUpdate(org.hibernate.annotations.SQLUpdate) SQLDeleteAll(org.hibernate.annotations.SQLDeleteAll) Persister(org.hibernate.annotations.Persister) ElementCollection(javax.persistence.ElementCollection) OptimisticLock(org.hibernate.annotations.OptimisticLock) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty)

Example 3 with SecondPass

use of org.hibernate.cfg.SecondPass in project hibernate-orm by hibernate.

the class IdBagBinder method bindStarToManySecondPass.

@Override
protected boolean bindStarToManySecondPass(Map persistentClasses, XClass collType, Ejb3JoinColumn[] fkJoinColumns, Ejb3JoinColumn[] keyColumns, Ejb3JoinColumn[] inverseColumns, Ejb3Column[] elementColumns, boolean isEmbedded, XProperty property, boolean unique, TableBinder associationTableBinder, boolean ignoreNotFound, MetadataBuildingContext buildingContext) {
    boolean result = super.bindStarToManySecondPass(persistentClasses, collType, fkJoinColumns, keyColumns, inverseColumns, elementColumns, isEmbedded, property, unique, associationTableBinder, ignoreNotFound, getBuildingContext());
    CollectionId collectionIdAnn = property.getAnnotation(CollectionId.class);
    if (collectionIdAnn != null) {
        SimpleValueBinder simpleValue = new SimpleValueBinder();
        PropertyData propertyData = new WrappedInferredData(new PropertyInferredData(null, property, // default access should not be useful
        null, buildingContext.getBootstrapContext().getReflectionManager()), "id");
        Ejb3Column[] idColumns = Ejb3Column.buildColumnFromAnnotation(collectionIdAnn.columns(), null, Nullability.FORCED_NOT_NULL, propertyHolder, propertyData, Collections.EMPTY_MAP, buildingContext);
        // we need to make sure all id columns must be not-null.
        for (Ejb3Column idColumn : idColumns) {
            idColumn.setNullable(false);
        }
        Table table = collection.getCollectionTable();
        simpleValue.setTable(table);
        simpleValue.setColumns(idColumns);
        Type typeAnn = collectionIdAnn.type();
        if (typeAnn != null && !BinderHelper.isEmptyAnnotationValue(typeAnn.type())) {
            simpleValue.setExplicitType(typeAnn);
        } else {
            throw new AnnotationException("@CollectionId is missing type: " + StringHelper.qualify(propertyHolder.getPath(), propertyName));
        }
        simpleValue.setBuildingContext(getBuildingContext());
        SimpleValue id = simpleValue.make();
        ((IdentifierCollection) collection).setIdentifier(id);
        String generator = collectionIdAnn.generator();
        String generatorType;
        if ("identity".equals(generator) || "assigned".equals(generator) || "sequence".equals(generator) || "native".equals(generator)) {
            generatorType = generator;
            generator = "";
        } else {
            generatorType = null;
        }
        SecondPass secondPass = new IdGeneratorResolverSecondPass(id, property, generatorType, generator, getBuildingContext());
        buildingContext.getMetadataCollector().addSecondPass(secondPass);
    }
    return result;
}
Also used : IdGeneratorResolverSecondPass(org.hibernate.cfg.IdGeneratorResolverSecondPass) WrappedInferredData(org.hibernate.cfg.WrappedInferredData) PropertyData(org.hibernate.cfg.PropertyData) Table(org.hibernate.mapping.Table) PropertyInferredData(org.hibernate.cfg.PropertyInferredData) SimpleValue(org.hibernate.mapping.SimpleValue) IdentifierCollection(org.hibernate.mapping.IdentifierCollection) Type(org.hibernate.annotations.Type) CollectionId(org.hibernate.annotations.CollectionId) IdGeneratorResolverSecondPass(org.hibernate.cfg.IdGeneratorResolverSecondPass) SecondPass(org.hibernate.cfg.SecondPass) AnnotationException(org.hibernate.AnnotationException) Ejb3Column(org.hibernate.cfg.Ejb3Column)

Aggregations

SecondPass (org.hibernate.cfg.SecondPass)3 AnnotationException (org.hibernate.AnnotationException)2 HashMap (java.util.HashMap)1 Map (java.util.Map)1 ElementCollection (javax.persistence.ElementCollection)1 Embeddable (javax.persistence.Embeddable)1 MapKeyColumn (javax.persistence.MapKeyColumn)1 MappingException (org.hibernate.MappingException)1 CollectionId (org.hibernate.annotations.CollectionId)1 LazyGroup (org.hibernate.annotations.LazyGroup)1 Loader (org.hibernate.annotations.Loader)1 OptimisticLock (org.hibernate.annotations.OptimisticLock)1 Persister (org.hibernate.annotations.Persister)1 SQLDelete (org.hibernate.annotations.SQLDelete)1 SQLDeleteAll (org.hibernate.annotations.SQLDeleteAll)1 SQLInsert (org.hibernate.annotations.SQLInsert)1 SQLUpdate (org.hibernate.annotations.SQLUpdate)1 Type (org.hibernate.annotations.Type)1 AssertionFailure (org.hibernate.annotations.common.AssertionFailure)1 XClass (org.hibernate.annotations.common.reflection.XClass)1