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));
}
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;
}
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));
}
}
}
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()));
}
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);
}
Aggregations