use of org.hibernate.envers.configuration.internal.metadata.reader.ClassAuditingData in project hibernate-orm by hibernate.
the class ClassesAuditingData method updateCalculatedFields.
/**
* After all meta-data is read, updates calculated fields. This includes:
* <ul>
* <li>setting {@code forceInsertable} to {@code true} for properties specified by {@code @AuditMappedBy}</li>
* <li>adding {@code synthetic} properties to mappedBy relations which have {@code IndexColumn} or {@code OrderColumn}.</li>
* </ul>
*/
public void updateCalculatedFields() {
for (Map.Entry<PersistentClass, ClassAuditingData> classAuditingDataEntry : persistentClassToAuditingData.entrySet()) {
final PersistentClass pc = classAuditingDataEntry.getKey();
final ClassAuditingData classAuditingData = classAuditingDataEntry.getValue();
for (String propertyName : classAuditingData.getNonSyntheticPropertyNames()) {
final Property property = pc.getProperty(propertyName);
updateCalculatedProperty(pc.getEntityName(), property, propertyName, classAuditingData);
}
}
}
use of org.hibernate.envers.configuration.internal.metadata.reader.ClassAuditingData in project hibernate-orm by hibernate.
the class EntitiesConfigurator method configure.
public EntitiesConfigurations configure(MetadataImplementor metadata, ServiceRegistry serviceRegistry, ReflectionManager reflectionManager, MappingCollector mappingCollector, GlobalConfiguration globalConfiguration, AuditEntitiesConfiguration auditEntitiesConfiguration, AuditStrategy auditStrategy, Document revisionInfoXmlMapping, Element revisionInfoRelationMapping) {
// Creating a name register to capture all audit entity names created.
final AuditEntityNameRegister auditEntityNameRegister = new AuditEntityNameRegister();
// Sorting the persistent class topologically - superclass always before subclass
final Iterator<PersistentClass> classes = GraphTopologicalSort.sort(new PersistentClassGraphDefiner(metadata)).iterator();
final ClassesAuditingData classesAuditingData = new ClassesAuditingData();
final Map<PersistentClass, EntityXmlMappingData> xmlMappings = new HashMap<>();
// Reading metadata from annotations
while (classes.hasNext()) {
final PersistentClass pc = classes.next();
// Ensure we're in POJO, not dynamic model, mapping.
if (pc.getClassName() != null) {
// Collecting information from annotations on the persistent class pc
final AnnotationsMetadataReader annotationsMetadataReader = new AnnotationsMetadataReader(globalConfiguration, reflectionManager, pc);
final ClassAuditingData auditData = annotationsMetadataReader.getAuditData();
classesAuditingData.addClassAuditingData(pc, auditData);
}
}
// Now that all information is read we can update the calculated fields.
classesAuditingData.updateCalculatedFields();
final AuditMetadataGenerator auditMetaGen = new AuditMetadataGenerator(metadata, serviceRegistry, globalConfiguration, auditEntitiesConfiguration, auditStrategy, revisionInfoRelationMapping, auditEntityNameRegister);
// First pass
for (Map.Entry<PersistentClass, ClassAuditingData> pcDatasEntry : classesAuditingData.getAllClassAuditedData()) {
final PersistentClass pc = pcDatasEntry.getKey();
final ClassAuditingData auditData = pcDatasEntry.getValue();
final EntityXmlMappingData xmlMappingData = new EntityXmlMappingData();
if (auditData.isAudited()) {
if (!StringTools.isEmpty(auditData.getAuditTable().value())) {
auditEntitiesConfiguration.addCustomAuditTableName(pc.getEntityName(), auditData.getAuditTable().value());
}
auditMetaGen.generateFirstPass(pc, auditData, xmlMappingData, true);
} else {
auditMetaGen.generateFirstPass(pc, auditData, xmlMappingData, false);
}
xmlMappings.put(pc, xmlMappingData);
}
// Second pass
for (Map.Entry<PersistentClass, ClassAuditingData> pcDatasEntry : classesAuditingData.getAllClassAuditedData()) {
final EntityXmlMappingData xmlMappingData = xmlMappings.get(pcDatasEntry.getKey());
if (pcDatasEntry.getValue().isAudited()) {
auditMetaGen.generateSecondPass(pcDatasEntry.getKey(), pcDatasEntry.getValue(), xmlMappingData);
try {
mappingCollector.addDocument(xmlMappingData.getMainXmlMapping());
for (Document additionalMapping : xmlMappingData.getAdditionalXmlMappings()) {
mappingCollector.addDocument(additionalMapping);
}
} catch (DocumentException e) {
throw new MappingException(e);
}
}
}
// Only if there are any versioned classes
if (auditMetaGen.getEntitiesConfigurations().size() > 0) {
try {
if (revisionInfoXmlMapping != null) {
mappingCollector.addDocument(revisionInfoXmlMapping);
}
} catch (DocumentException e) {
throw new MappingException(e);
}
}
return new EntitiesConfigurations(auditMetaGen.getEntitiesConfigurations(), auditMetaGen.getNotAuditedEntitiesConfigurations());
}
use of org.hibernate.envers.configuration.internal.metadata.reader.ClassAuditingData in project hibernate-orm by hibernate.
the class ClassesAuditingData method updateCalculatedProperty.
private void updateCalculatedProperty(String entityName, Property property, String propertyName, AuditedPropertiesHolder propertyHolder) {
final PropertyAuditingData propertyAuditingData = propertyHolder.getPropertyAuditingData(propertyName);
final boolean isAuditMappedBy = propertyAuditingData.getAuditMappedBy() != null;
final boolean isRelationMappedBy = propertyAuditingData.getRelationMappedBy() != null;
// handle updating the property, if applicable.
if (isAuditMappedBy || isRelationMappedBy) {
final String referencedEntityName = MappingTools.getReferencedEntityName(property.getValue());
final ClassAuditingData referencedAuditData = entityNameToAuditingData.get(referencedEntityName);
if (isAuditMappedBy) {
// If a property had the @AuditMappedBy annotation, setting the referenced fields to be always insertable.
setAuditMappedByInsertable(referencedEntityName, entityName, referencedAuditData, propertyAuditingData);
} else if (isRelationMappedBy && (property.getValue() instanceof List)) {
// If a property has mappedBy= and @Indexed and isn't @AuditMappedBy, add synthetic support.
addSyntheticIndexProperty((List) property.getValue(), property.getPropertyAccessorName(), referencedAuditData);
}
}
// This is useful for AuditMappedBy inside an Embeddable that holds a collection of entities.
if (propertyAuditingData instanceof ComponentAuditingData) {
final ComponentAuditingData componentAuditingData = (ComponentAuditingData) propertyAuditingData;
final Component component = (Component) property.getValue();
for (String componentPropertyName : componentAuditingData.getNonSyntheticPropertyNames()) {
final Property componentProperty = component.getProperty(componentPropertyName);
updateCalculatedProperty(entityName, componentProperty, componentPropertyName, componentAuditingData);
}
}
}
Aggregations