Search in sources :

Example 1 with RelationQueryGenerator

use of org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator in project hibernate-orm by hibernate.

the class CollectionMetadataGenerator method addWithMiddleTable.

@SuppressWarnings({ "unchecked" })
private void addWithMiddleTable() {
    LOG.debugf("Adding audit mapping for property %s.%s: collection with a join table", referencingEntityName, propertyName);
    // Generating the name of the middle table
    String auditMiddleTableName;
    String auditMiddleEntityName;
    if (!StringTools.isEmpty(propertyAuditingData.getJoinTable().name())) {
        auditMiddleTableName = propertyAuditingData.getJoinTable().name();
        auditMiddleEntityName = propertyAuditingData.getJoinTable().name();
    } else {
        final String middleTableName = getMiddleTableName(propertyValue, referencingEntityName);
        auditMiddleTableName = mainGenerator.getVerEntCfg().getAuditTableName(null, middleTableName);
        auditMiddleEntityName = mainGenerator.getVerEntCfg().getAuditEntityName(middleTableName);
    }
    LOG.debugf("Using join table name: %s", auditMiddleTableName);
    // Generating the XML mapping for the middle entity, only if the relation isn't inverse.
    // If the relation is inverse, will be later checked by comparing middleEntityXml with null.
    Element middleEntityXml;
    if (!propertyValue.isInverse()) {
        // Generating a unique middle entity name
        auditMiddleEntityName = mainGenerator.getAuditEntityNameRegister().createUnique(auditMiddleEntityName);
        // Registering the generated name
        mainGenerator.getAuditEntityNameRegister().register(auditMiddleEntityName);
        middleEntityXml = createMiddleEntityXml(auditMiddleTableName, auditMiddleEntityName, propertyValue.getWhere());
    } else {
        middleEntityXml = null;
    }
    // ******
    // Generating the mapping for the referencing entity (it must be an entity).
    // ******
    // Getting the id-mapping data of the referencing entity (the entity that "owns" this collection).
    final IdMappingData referencingIdMapping = referencingEntityConfiguration.getIdMappingData();
    // Only valid for an inverse relation; null otherwise.
    String mappedBy;
    // The referencing prefix is always for a related entity. So it has always the "_" at the end added.
    String referencingPrefixRelated;
    String referencedPrefix;
    if (propertyValue.isInverse()) {
        // If the relation is inverse, then referencedEntityName is not null.
        mappedBy = getMappedBy(propertyValue.getCollectionTable(), mainGenerator.getMetadata().getEntityBinding(referencedEntityName));
        referencingPrefixRelated = mappedBy + "_";
        referencedPrefix = StringTools.getLastComponent(referencedEntityName);
    } else {
        mappedBy = null;
        referencingPrefixRelated = StringTools.getLastComponent(referencingEntityName) + "_";
        referencedPrefix = referencedEntityName == null ? "element" : propertyName;
    }
    // Storing the id data of the referencing entity: original mapper, prefixed mapper and entity name.
    final MiddleIdData referencingIdData = createMiddleIdData(referencingIdMapping, referencingPrefixRelated, referencingEntityName);
    // Creating a query generator builder, to which additional id data will be added, in case this collection
    // references some entities (either from the element or index). At the end, this will be used to build
    // a query generator to read the raw data collection from the middle table.
    final QueryGeneratorBuilder queryGeneratorBuilder = new QueryGeneratorBuilder(mainGenerator.getGlobalCfg(), mainGenerator.getVerEntCfg(), mainGenerator.getAuditStrategy(), referencingIdData, auditMiddleEntityName, isRevisionTypeInId());
    // Adding the XML mapping for the referencing entity, if the relation isn't inverse.
    if (middleEntityXml != null) {
        // Adding related-entity (in this case: the referencing's entity id) id mapping to the xml.
        addRelatedToXmlMapping(middleEntityXml, referencingPrefixRelated, MetadataTools.getColumnNameIterator(propertyValue.getKey().getColumnIterator()), referencingIdMapping);
    }
    // ******
    // Generating the element mapping.
    // ******
    final MiddleComponentData elementComponentData = addValueToMiddleTable(propertyValue.getElement(), middleEntityXml, queryGeneratorBuilder, referencedPrefix, propertyAuditingData.getJoinTable().inverseJoinColumns(), !isLobMapElementType());
    // ******
    // Generating the index mapping, if an index exists.
    // ******
    final MiddleComponentData indexComponentData = addIndex(middleEntityXml, queryGeneratorBuilder);
    // ******
    // Generating the property mapper.
    // ******
    // Building the query generator.
    final RelationQueryGenerator queryGenerator = queryGeneratorBuilder.build(elementComponentData, indexComponentData);
    // Creating common data
    final CommonCollectionMapperData commonCollectionMapperData = new CommonCollectionMapperData(mainGenerator.getVerEntCfg(), auditMiddleEntityName, propertyAuditingData.getPropertyData(), referencingIdData, queryGenerator);
    // Checking the type of the collection and adding an appropriate mapper.
    addMapper(commonCollectionMapperData, elementComponentData, indexComponentData);
    // ******
    // Storing information about this relation.
    // ******
    storeMiddleEntityRelationInformation(mappedBy);
}
Also used : MiddleIdData(org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData) RelationQueryGenerator(org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator) CommonCollectionMapperData(org.hibernate.envers.internal.entities.mapper.relation.CommonCollectionMapperData) Element(org.dom4j.Element) MiddleComponentData(org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData) IdMappingData(org.hibernate.envers.internal.entities.IdMappingData)

Example 2 with RelationQueryGenerator

use of org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator in project hibernate-orm by hibernate.

the class CollectionMetadataGenerator method addOneToManyAttached.

@SuppressWarnings({ "unchecked" })
private void addOneToManyAttached(boolean fakeOneToManyBidirectional) {
    LOG.debugf("Adding audit mapping for property %s.%s: one-to-many collection, using a join column on the referenced entity", referencingEntityName, propertyName);
    // check whether the property has an @IndexColumn or @OrderColumn because its part of an
    // IndexedCollection mapping type.
    final boolean indexed = (propertyValue instanceof IndexedCollection) && ((IndexedCollection) propertyValue).getIndex() != null;
    final String mappedBy = getMappedBy(propertyValue);
    final IdMappingData referencedIdMapping = mainGenerator.getReferencedIdMappingData(referencingEntityName, referencedEntityName, propertyAuditingData, false);
    final IdMappingData referencingIdMapping = referencingEntityConfiguration.getIdMappingData();
    // Generating the id mappers data for the referencing side of the relation.
    final MiddleIdData referencingIdData = createMiddleIdData(referencingIdMapping, mappedBy + "_", referencingEntityName);
    // And for the referenced side. The prefixed mapper won't be used (as this collection isn't persisted
    // in a join table, so the prefix value is arbitrary).
    final MiddleIdData referencedIdData = createMiddleIdData(referencedIdMapping, null, referencedEntityName);
    // Generating the element mapping.
    final MiddleComponentData elementComponentData = new MiddleComponentData(new MiddleRelatedComponentMapper(referencedIdData), 0);
    // Generating the index mapping, if an index exists. It can only exists in case a javax.persistence.MapKey
    // annotation is present on the entity. So the middleEntityXml will be not be used. The queryGeneratorBuilder
    // will only be checked for nullnes.
    MiddleComponentData indexComponentData = addIndex(null, null);
    // Generating the query generator - it should read directly from the related entity.
    final RelationQueryGenerator queryGenerator = new OneAuditEntityQueryGenerator(mainGenerator.getGlobalCfg(), mainGenerator.getVerEntCfg(), mainGenerator.getAuditStrategy(), referencingIdData, referencedEntityName, referencedIdData, isEmbeddableElementType(), mappedBy, isMappedByKey(propertyValue, mappedBy));
    // Creating common mapper data.
    final CommonCollectionMapperData commonCollectionMapperData = new CommonCollectionMapperData(mainGenerator.getVerEntCfg(), referencedEntityName, propertyAuditingData.getPropertyData(), referencingIdData, queryGenerator);
    PropertyMapper fakeBidirectionalRelationMapper;
    PropertyMapper fakeBidirectionalRelationIndexMapper;
    if (fakeOneToManyBidirectional || indexed) {
        // In case of a fake many-to-one bidirectional relation, we have to generate a mapper which maps
        // the mapped-by property name to the id of the related entity (which is the owner of the collection).
        final String auditMappedBy;
        if (fakeOneToManyBidirectional) {
            auditMappedBy = propertyAuditingData.getAuditMappedBy();
        } else {
            auditMappedBy = propertyValue.getMappedByProperty();
        }
        // Creating a prefixed relation mapper.
        final IdMapper relMapper = referencingIdMapping.getIdMapper().prefixMappedProperties(MappingTools.createToOneRelationPrefix(auditMappedBy));
        fakeBidirectionalRelationMapper = new ToOneIdMapper(relMapper, // when constructing the PropertyData.
        new PropertyData(auditMappedBy, null, null, null), referencingEntityName, false);
        final String positionMappedBy;
        if (fakeOneToManyBidirectional) {
            positionMappedBy = propertyAuditingData.getPositionMappedBy();
        } else if (indexed) {
            final Value indexValue = ((IndexedCollection) propertyValue).getIndex();
            positionMappedBy = indexValue.getColumnIterator().next().getText();
        } else {
            positionMappedBy = null;
        }
        // Checking if there's an index defined. If so, adding a mapper for it.
        if (positionMappedBy != null) {
            fakeBidirectionalRelationIndexMapper = new SinglePropertyMapper(new PropertyData(positionMappedBy, null, null, null));
            // Also, overwriting the index component data to properly read the index.
            indexComponentData = new MiddleComponentData(new MiddleStraightComponentMapper(positionMappedBy), 0);
        } else {
            fakeBidirectionalRelationIndexMapper = null;
        }
    } else {
        fakeBidirectionalRelationMapper = null;
        fakeBidirectionalRelationIndexMapper = null;
    }
    // Checking the type of the collection and adding an appropriate mapper.
    addMapper(commonCollectionMapperData, elementComponentData, indexComponentData);
    // Storing information about this relation.
    referencingEntityConfiguration.addToManyNotOwningRelation(propertyName, mappedBy, referencedEntityName, referencingIdData.getPrefixedMapper(), fakeBidirectionalRelationMapper, fakeBidirectionalRelationIndexMapper, indexed);
}
Also used : PropertyData(org.hibernate.envers.internal.entities.PropertyData) CommonCollectionMapperData(org.hibernate.envers.internal.entities.mapper.relation.CommonCollectionMapperData) MiddleRelatedComponentMapper(org.hibernate.envers.internal.entities.mapper.relation.component.MiddleRelatedComponentMapper) IdMapper(org.hibernate.envers.internal.entities.mapper.id.IdMapper) ToOneIdMapper(org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper) SinglePropertyMapper(org.hibernate.envers.internal.entities.mapper.SinglePropertyMapper) MultiPropertyMapper(org.hibernate.envers.internal.entities.mapper.MultiPropertyMapper) SinglePropertyMapper(org.hibernate.envers.internal.entities.mapper.SinglePropertyMapper) PropertyMapper(org.hibernate.envers.internal.entities.mapper.PropertyMapper) MiddleIdData(org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData) RelationQueryGenerator(org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator) Value(org.hibernate.mapping.Value) MiddleComponentData(org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData) ToOneIdMapper(org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper) OneAuditEntityQueryGenerator(org.hibernate.envers.internal.entities.mapper.relation.query.OneAuditEntityQueryGenerator) IndexedCollection(org.hibernate.mapping.IndexedCollection) MiddleStraightComponentMapper(org.hibernate.envers.internal.entities.mapper.relation.component.MiddleStraightComponentMapper) IdMappingData(org.hibernate.envers.internal.entities.IdMappingData)

Aggregations

IdMappingData (org.hibernate.envers.internal.entities.IdMappingData)2 CommonCollectionMapperData (org.hibernate.envers.internal.entities.mapper.relation.CommonCollectionMapperData)2 MiddleComponentData (org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData)2 MiddleIdData (org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData)2 RelationQueryGenerator (org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator)2 Element (org.dom4j.Element)1 PropertyData (org.hibernate.envers.internal.entities.PropertyData)1 MultiPropertyMapper (org.hibernate.envers.internal.entities.mapper.MultiPropertyMapper)1 PropertyMapper (org.hibernate.envers.internal.entities.mapper.PropertyMapper)1 SinglePropertyMapper (org.hibernate.envers.internal.entities.mapper.SinglePropertyMapper)1 IdMapper (org.hibernate.envers.internal.entities.mapper.id.IdMapper)1 ToOneIdMapper (org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper)1 MiddleRelatedComponentMapper (org.hibernate.envers.internal.entities.mapper.relation.component.MiddleRelatedComponentMapper)1 MiddleStraightComponentMapper (org.hibernate.envers.internal.entities.mapper.relation.component.MiddleStraightComponentMapper)1 OneAuditEntityQueryGenerator (org.hibernate.envers.internal.entities.mapper.relation.query.OneAuditEntityQueryGenerator)1 IndexedCollection (org.hibernate.mapping.IndexedCollection)1 Value (org.hibernate.mapping.Value)1