Search in sources :

Example 1 with CollectionChangeWorkUnit

use of org.hibernate.envers.internal.synchronization.work.CollectionChangeWorkUnit 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 2 with CollectionChangeWorkUnit

use of org.hibernate.envers.internal.synchronization.work.CollectionChangeWorkUnit 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 3 with CollectionChangeWorkUnit

use of org.hibernate.envers.internal.synchronization.work.CollectionChangeWorkUnit in project hibernate-orm by hibernate.

the class BaseEnversEventListener method addCollectionChangeWorkUnit.

private void addCollectionChangeWorkUnit(AuditProcess auditProcess, SessionImplementor session, String fromEntityName, RelationDescription relDesc, Object value) {
    // relDesc.getToEntityName() doesn't always return the entity name of the value - in case
    // of subclasses, this will be root class, no the actual class. So it can't be used here.
    String toEntityName;
    Serializable id;
    if (value instanceof HibernateProxy) {
        final HibernateProxy hibernateProxy = (HibernateProxy) value;
        id = hibernateProxy.getHibernateLazyInitializer().getIdentifier();
        // We've got to initialize the object from the proxy to later read its state.
        value = EntityTools.getTargetFromProxy(session.getFactory(), hibernateProxy);
        // HHH-7249
        // This call must occur after the proxy has been initialized or the returned name will
        // be to the base class which will impact the discriminator value chosen when using an
        // inheritance strategy with discriminators.
        toEntityName = session.bestGuessEntityName(value);
    } else {
        toEntityName = session.guessEntityName(value);
        final IdMapper idMapper = enversService.getEntitiesConfigurations().get(toEntityName).getIdMapper();
        id = (Serializable) idMapper.mapToIdFromEntity(value);
    }
    final Set<String> toPropertyNames = enversService.getEntitiesConfigurations().getToPropertyNames(fromEntityName, relDesc.getFromPropertyName(), toEntityName);
    final String toPropertyName = toPropertyNames.iterator().next();
    auditProcess.addWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, toPropertyName, enversService, id, value));
}
Also used : Serializable(java.io.Serializable) IdMapper(org.hibernate.envers.internal.entities.mapper.id.IdMapper) HibernateProxy(org.hibernate.proxy.HibernateProxy) CollectionChangeWorkUnit(org.hibernate.envers.internal.synchronization.work.CollectionChangeWorkUnit)

Example 4 with CollectionChangeWorkUnit

use of org.hibernate.envers.internal.synchronization.work.CollectionChangeWorkUnit in project hibernate-orm by hibernate.

the class BaseEnversCollectionEventListener method onCollectionAction.

protected final void onCollectionAction(AbstractCollectionEvent event, PersistentCollection newColl, Serializable oldColl, CollectionEntry collectionEntry) {
    if (shouldGenerateRevision(event)) {
        checkIfTransactionInProgress(event.getSession());
        final AuditProcess auditProcess = getEnversService().getAuditProcessManager().get(event.getSession());
        final String entityName = event.getAffectedOwnerEntityName();
        final String ownerEntityName = ((AbstractCollectionPersister) collectionEntry.getLoadedPersister()).getOwnerEntityName();
        final String referencingPropertyName = collectionEntry.getRole().substring(ownerEntityName.length() + 1);
        // Checking if this is not a "fake" many-to-one bidirectional relation. The relation description may be
        // null in case of collections of non-entities.
        final RelationDescription rd = searchForRelationDescription(entityName, referencingPropertyName);
        if (rd != null && rd.getMappedByPropertyName() != null) {
            generateFakeBidirecationalRelationWorkUnits(auditProcess, newColl, oldColl, entityName, referencingPropertyName, event, rd);
        } else {
            final PersistentCollectionChangeWorkUnit workUnit = new PersistentCollectionChangeWorkUnit(event.getSession(), entityName, getEnversService(), newColl, collectionEntry, oldColl, event.getAffectedOwnerIdOrNull(), referencingPropertyName);
            auditProcess.addWorkUnit(workUnit);
            if (workUnit.containsWork()) {
                // There are some changes: a revision needs also be generated for the collection owner
                auditProcess.addWorkUnit(new CollectionChangeWorkUnit(event.getSession(), event.getAffectedOwnerEntityName(), referencingPropertyName, getEnversService(), event.getAffectedOwnerIdOrNull(), event.getAffectedOwnerOrNull()));
                generateBidirectionalCollectionChangeWorkUnits(auditProcess, event, workUnit, rd);
            }
        }
    }
}
Also used : AuditProcess(org.hibernate.envers.internal.synchronization.AuditProcess) RelationDescription(org.hibernate.envers.internal.entities.RelationDescription) PersistentCollectionChangeWorkUnit(org.hibernate.envers.internal.synchronization.work.PersistentCollectionChangeWorkUnit) AbstractCollectionPersister(org.hibernate.persister.collection.AbstractCollectionPersister) CollectionChangeWorkUnit(org.hibernate.envers.internal.synchronization.work.CollectionChangeWorkUnit) PersistentCollectionChangeWorkUnit(org.hibernate.envers.internal.synchronization.work.PersistentCollectionChangeWorkUnit)

Aggregations

CollectionChangeWorkUnit (org.hibernate.envers.internal.synchronization.work.CollectionChangeWorkUnit)4 Serializable (java.io.Serializable)3 IdMapper (org.hibernate.envers.internal.entities.mapper.id.IdMapper)3 PersistentCollectionChangeWorkUnit (org.hibernate.envers.internal.synchronization.work.PersistentCollectionChangeWorkUnit)3 PersistentCollectionChangeData (org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData)2 RevisionType (org.hibernate.envers.RevisionType)1 RelationDescription (org.hibernate.envers.internal.entities.RelationDescription)1 AuditProcess (org.hibernate.envers.internal.synchronization.AuditProcess)1 AuditWorkUnit (org.hibernate.envers.internal.synchronization.work.AuditWorkUnit)1 FakeBidirectionalRelationWorkUnit (org.hibernate.envers.internal.synchronization.work.FakeBidirectionalRelationWorkUnit)1 AbstractCollectionPersister (org.hibernate.persister.collection.AbstractCollectionPersister)1 HibernateProxy (org.hibernate.proxy.HibernateProxy)1