Search in sources :

Example 1 with IdMapper

use of org.hibernate.envers.internal.entities.mapper.id.IdMapper in project hibernate-orm by hibernate.

the class ToOneRelationMetadataGenerator method addToOne.

@SuppressWarnings({ "unchecked" })
void addToOne(Element parent, PropertyAuditingData propertyAuditingData, Value value, CompositeMapperBuilder mapper, String entityName, boolean insertable) {
    final String referencedEntityName = ((ToOne) value).getReferencedEntityName();
    final IdMappingData idMapping = mainGenerator.getReferencedIdMappingData(entityName, referencedEntityName, propertyAuditingData, true);
    final String lastPropertyPrefix = MappingTools.createToOneRelationPrefix(propertyAuditingData.getName());
    // Generating the id mapper for the relation
    final IdMapper relMapper = idMapping.getIdMapper().prefixMappedProperties(lastPropertyPrefix);
    // Storing information about this relation
    mainGenerator.getEntitiesConfigurations().get(entityName).addToOneRelation(propertyAuditingData.getName(), referencedEntityName, relMapper, insertable, MappingTools.ignoreNotFound(value));
    // If the property isn't insertable, checking if this is not a "fake" bidirectional many-to-one relationship,
    // that is, when the one side owns the relation (and is a collection), and the many side is non insertable.
    // When that's the case and the user specified to store this relation without a middle table (using
    // @AuditMappedBy), we have to make the property insertable for the purposes of Envers. In case of changes to
    // the entity that didn't involve the relation, it's value will then be stored properly. In case of changes
    // to the entity that did involve the relation, it's the responsibility of the collection side to store the
    // proper data.
    boolean nonInsertableFake;
    if (!insertable && propertyAuditingData.isForceInsertable()) {
        nonInsertableFake = true;
        insertable = true;
    } else {
        nonInsertableFake = false;
    }
    // Adding an element to the mapping corresponding to the references entity id's
    final Element properties = (Element) idMapping.getXmlRelationMapping().clone();
    properties.addAttribute("name", propertyAuditingData.getName());
    MetadataTools.prefixNamesInPropertyElement(properties, lastPropertyPrefix, MetadataTools.getColumnNameIterator(value.getColumnIterator()), false, insertable);
    // Extracting related id properties from properties tag
    for (Object o : properties.content()) {
        final Element element = (Element) o;
        element.setParent(null);
        parent.add(element);
    }
    // Adding mapper for the id
    final PropertyData propertyData = propertyAuditingData.getPropertyData();
    mapper.addComposite(propertyData, new ToOneIdMapper(relMapper, propertyData, referencedEntityName, nonInsertableFake));
}
Also used : PropertyData(org.hibernate.envers.internal.entities.PropertyData) Element(org.dom4j.Element) OneToOne(org.hibernate.mapping.OneToOne) ToOne(org.hibernate.mapping.ToOne) IdMapper(org.hibernate.envers.internal.entities.mapper.id.IdMapper) ToOneIdMapper(org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper) ToOneIdMapper(org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper) IdMappingData(org.hibernate.envers.internal.entities.IdMappingData)

Example 2 with IdMapper

use of org.hibernate.envers.internal.entities.mapper.id.IdMapper in project hibernate-orm by hibernate.

the class OneAuditEntityQueryGenerator method commonQueryPart.

/**
	 * Compute common part for both queries.
	 */
private QueryBuilder commonQueryPart(String versionsReferencedEntityName) {
    // SELECT e FROM versionsEntity e
    final QueryBuilder qb = new QueryBuilder(versionsReferencedEntityName, REFERENCED_ENTITY_ALIAS);
    qb.addProjection(null, REFERENCED_ENTITY_ALIAS, null, false);
    // WHERE
    if (multipleIdMapperKey) {
        // HHH-7625
        // support @OneToMany(mappedBy) to @ManyToOne @IdClass attribute.
        // e.originalId.id_ref_ed.id = :id_ref_ed
        final IdMapper mapper = getMultipleIdPrefixedMapper();
        mapper.addNamedIdEqualsToQuery(qb.getRootParameters(), null, referencingIdData.getPrefixedMapper(), true);
    } else {
        // e.id_ref_ed = :id_ref_ed
        referencingIdData.getPrefixedMapper().addNamedIdEqualsToQuery(qb.getRootParameters(), null, true);
    }
    return qb;
}
Also used : IdMapper(org.hibernate.envers.internal.entities.mapper.id.IdMapper) MultipleIdMapper(org.hibernate.envers.internal.entities.mapper.id.MultipleIdMapper) QueryBuilder(org.hibernate.envers.internal.tools.query.QueryBuilder)

Example 3 with IdMapper

use of org.hibernate.envers.internal.entities.mapper.id.IdMapper in project hibernate-orm by hibernate.

the class BaseEnversCollectionEventListener method generateBidirectionalCollectionChangeWorkUnits.

private void generateBidirectionalCollectionChangeWorkUnits(AuditProcess auditProcess, AbstractCollectionEvent event, PersistentCollectionChangeWorkUnit workUnit, RelationDescription rd) {
    // Checking if this is enabled in configuration ...
    if (!getEnversService().getGlobalConfiguration().isGenerateRevisionsForCollections()) {
        return;
    }
    // relDesc can be null if this is a collection of simple values (not a relation).
    if (rd != null && rd.isBidirectional()) {
        final String relatedEntityName = rd.getToEntityName();
        final IdMapper relatedIdMapper = getEnversService().getEntitiesConfigurations().get(relatedEntityName).getIdMapper();
        final Set<String> toPropertyNames = getEnversService().getEntitiesConfigurations().getToPropertyNames(event.getAffectedOwnerEntityName(), rd.getFromPropertyName(), relatedEntityName);
        final String toPropertyName = toPropertyNames.iterator().next();
        for (PersistentCollectionChangeData changeData : workUnit.getCollectionChanges()) {
            final Object relatedObj = changeData.getChangedElement();
            final Serializable relatedId = (Serializable) relatedIdMapper.mapToIdFromEntity(relatedObj);
            auditProcess.addWorkUnit(new CollectionChangeWorkUnit(event.getSession(), event.getSession().bestGuessEntityName(relatedObj), toPropertyName, getEnversService(), relatedId, relatedObj));
        }
    }
}
Also used : Serializable(java.io.Serializable) IdMapper(org.hibernate.envers.internal.entities.mapper.id.IdMapper) PersistentCollectionChangeData(org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData) CollectionChangeWorkUnit(org.hibernate.envers.internal.synchronization.work.CollectionChangeWorkUnit) PersistentCollectionChangeWorkUnit(org.hibernate.envers.internal.synchronization.work.PersistentCollectionChangeWorkUnit)

Example 4 with IdMapper

use of org.hibernate.envers.internal.entities.mapper.id.IdMapper in project hibernate-orm by hibernate.

the class BaseEnversCollectionEventListener method generateFakeBidirecationalRelationWorkUnits.

private void generateFakeBidirecationalRelationWorkUnits(AuditProcess auditProcess, PersistentCollection newColl, Serializable oldColl, String collectionEntityName, String referencingPropertyName, AbstractCollectionEvent event, RelationDescription rd) {
    // First computing the relation changes
    final List<PersistentCollectionChangeData> collectionChanges = getEnversService().getEntitiesConfigurations().get(collectionEntityName).getPropertyMapper().mapCollectionChanges(event.getSession(), referencingPropertyName, newColl, oldColl, event.getAffectedOwnerIdOrNull());
    // Getting the id mapper for the related entity, as the work units generated will correspond to the related
    // entities.
    final String relatedEntityName = rd.getToEntityName();
    final IdMapper relatedIdMapper = getEnversService().getEntitiesConfigurations().get(relatedEntityName).getIdMapper();
    // For each collection change, generating the bidirectional work unit.
    for (PersistentCollectionChangeData changeData : collectionChanges) {
        final Object relatedObj = changeData.getChangedElement();
        final Serializable relatedId = (Serializable) relatedIdMapper.mapToIdFromEntity(relatedObj);
        final RevisionType revType = (RevisionType) changeData.getData().get(getEnversService().getAuditEntitiesConfiguration().getRevisionTypePropName());
        // This can be different from relatedEntityName, in case of inheritance (the real entity may be a subclass
        // of relatedEntityName).
        final String realRelatedEntityName = event.getSession().bestGuessEntityName(relatedObj);
        // By default, the nested work unit is a collection change work unit.
        final AuditWorkUnit nestedWorkUnit = new CollectionChangeWorkUnit(event.getSession(), realRelatedEntityName, rd.getMappedByPropertyName(), getEnversService(), relatedId, relatedObj);
        auditProcess.addWorkUnit(new FakeBidirectionalRelationWorkUnit(event.getSession(), realRelatedEntityName, getEnversService(), relatedId, referencingPropertyName, event.getAffectedOwnerOrNull(), rd, revType, changeData.getChangedElementIndex(), nestedWorkUnit));
    }
    // We also have to generate a collection change work unit for the owning entity.
    auditProcess.addWorkUnit(new CollectionChangeWorkUnit(event.getSession(), collectionEntityName, referencingPropertyName, getEnversService(), event.getAffectedOwnerIdOrNull(), event.getAffectedOwnerOrNull()));
}
Also used : Serializable(java.io.Serializable) RevisionType(org.hibernate.envers.RevisionType) IdMapper(org.hibernate.envers.internal.entities.mapper.id.IdMapper) AuditWorkUnit(org.hibernate.envers.internal.synchronization.work.AuditWorkUnit) FakeBidirectionalRelationWorkUnit(org.hibernate.envers.internal.synchronization.work.FakeBidirectionalRelationWorkUnit) PersistentCollectionChangeData(org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData) CollectionChangeWorkUnit(org.hibernate.envers.internal.synchronization.work.CollectionChangeWorkUnit) PersistentCollectionChangeWorkUnit(org.hibernate.envers.internal.synchronization.work.PersistentCollectionChangeWorkUnit)

Example 5 with IdMapper

use of org.hibernate.envers.internal.entities.mapper.id.IdMapper 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

IdMapper (org.hibernate.envers.internal.entities.mapper.id.IdMapper)10 IdMappingData (org.hibernate.envers.internal.entities.IdMappingData)4 PropertyData (org.hibernate.envers.internal.entities.PropertyData)4 ToOneIdMapper (org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper)4 Serializable (java.io.Serializable)3 CollectionChangeWorkUnit (org.hibernate.envers.internal.synchronization.work.CollectionChangeWorkUnit)3 OneToOne (org.hibernate.mapping.OneToOne)3 PersistentCollectionChangeData (org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData)2 MiddleIdData (org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData)2 PersistentCollectionChangeWorkUnit (org.hibernate.envers.internal.synchronization.work.PersistentCollectionChangeWorkUnit)2 ToOne (org.hibernate.mapping.ToOne)2 Map (java.util.Map)1 Element (org.dom4j.Element)1 MappingException (org.hibernate.MappingException)1 RevisionType (org.hibernate.envers.RevisionType)1 AuditEntitiesConfiguration (org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration)1 AuditException (org.hibernate.envers.exception.AuditException)1 EntityConfiguration (org.hibernate.envers.internal.entities.EntityConfiguration)1 MultiPropertyMapper (org.hibernate.envers.internal.entities.mapper.MultiPropertyMapper)1 PropertyMapper (org.hibernate.envers.internal.entities.mapper.PropertyMapper)1