public bool AddBasic(XmlElement parent, PropertyAuditingData propertyAuditingData, IValue value, ISimpleMapperBuilder mapper, bool insertable, bool key) { NHibernate.Type.IType type = value.Type; if (type is ImmutableType || type is MutableType) { AddSimpleValue(parent, propertyAuditingData, value, mapper, insertable, key); } else if (type is CustomType || type is CompositeCustomType) { AddCustomValue(parent, propertyAuditingData, value, mapper, insertable, key); } // TODO Simon: There is no equivalent of PrimitiveByteArrayBlobType in NHibernate, will see later if needed // ORIG: //else if ("org.hibernate.type.PrimitiveByteArrayBlobType".equals(type.getClass().getName())) //{ // AddSimpleValue(parent, propertyAuditingData, value, mapper, insertable, key); //} else { return(false); } return(true); }
/// <summary> /// Ctor /// </summary> /// <param name="metaDataStore"></param> /// <param name="mainGenerator">Main generator, giving access to configuration and the basic mapper.</param> /// <param name="propertyValue">Value of the collection, as mapped by Hibernate.</param> /// <param name="currentMapper">Mapper, to which the appropriate {@link org.hibernate.envers.entities.mapper.PropertyMapper} will be added.</param> /// <param name="referencingEntityName">Name of the entity that owns this collection.</param> /// <param name="xmlMappingData">In case this collection requires a middle table, additional mapping documents will be created using this object.</param> /// <param name="propertyAuditingData"> /// Property auditing (meta-)data. Among other things, holds the name of the /// property that references the collection in the referencing entity, the user data for middle (join) /// table and the value of the <code>@MapKey</code> annotation, if there was one. /// </param> public CollectionMetadataGenerator(IMetaDataStore metaDataStore, AuditMetadataGenerator mainGenerator, Mapping.Collection propertyValue, ICompositeMapperBuilder currentMapper, string referencingEntityName, EntityXmlMappingData xmlMappingData, PropertyAuditingData propertyAuditingData) { _metaDataStore = metaDataStore; _mainGenerator = mainGenerator; _propertyValue = propertyValue; _currentMapper = currentMapper; _referencingEntityName = referencingEntityName; _xmlMappingData = xmlMappingData; _propertyAuditingData = propertyAuditingData; _propertyName = propertyAuditingData.Name; _referencingEntityConfiguration = mainGenerator.EntitiesConfigurations[referencingEntityName]; if (_referencingEntityConfiguration == null) { throw new MappingException("Unable to read auditing configuration for " + referencingEntityName + "!"); } _referencedEntityName = MappingTools.ReferencedEntityName(propertyValue.Element); }
/** * Reads the id mapping data of a referenced entity. * @param entityName Name of the entity which is the source of the relation. * @param referencedEntityName Name of the entity which is the target of the relation. * @param propertyAuditingData Auditing data of the property that is the source of the relation. * @param allowNotAuditedTarget Are not-audited target entities allowed. * @throws MappingException If a relation from an audited to a non-audited entity is detected, which is not * mapped using {@link RelationTargetAuditMode#NotAudited}. * @return The id mapping data of the related entity. */ public IdMappingData GetReferencedIdMappingData(string entityName, string referencedEntityName, PropertyAuditingData propertyAuditingData, bool allowNotAuditedTarget) { EntityConfiguration configuration; if (EntitiesConfigurations.Keys.Contains(referencedEntityName)) { configuration = EntitiesConfigurations[referencedEntityName]; } else { var relationTargetAuditMode = propertyAuditingData.RelationTargetAuditMode; if (!NotAuditedEntitiesConfigurations.Keys.Contains(referencedEntityName) || !allowNotAuditedTarget || !RelationTargetAuditMode.NotAudited.Equals(relationTargetAuditMode)) { throw new MappingException("An audited relation from " + entityName + "." + propertyAuditingData.Name + " to a not audited entity " + referencedEntityName + "!" + (allowNotAuditedTarget ? " Such mapping is possible, but has to be explicitly defined using [Audited(TargetAuditMode = RelationTargetAuditMode.NotAudited)]." : string.Empty)); } configuration = NotAuditedEntitiesConfigurations[referencedEntityName]; } return(configuration.IdMappingData); }
public bool AddBasic(XElement parent, PropertyAuditingData propertyAuditingData, IValue value, ISimpleMapperBuilder mapper, bool insertable, bool key) { var type = value.Type; var custType = type as CustomType; var compType = type as CompositeCustomType; if (type is ImmutableType || type is MutableType) { var mappingType = type.GetType(); var userDefined = isUserDefined(mappingType); if (userDefined) { addCustomValue(parent, propertyAuditingData, value, mapper, insertable, key, mappingType); } else { addSimpleValue(parent, propertyAuditingData, value, mapper, insertable, key); } } else if (custType != null) { addCustomValue(parent, propertyAuditingData, value, mapper, insertable, key, custType.UserType.GetType()); } else if (compType != null) { addCustomValue(parent, propertyAuditingData, value, mapper, insertable, key, compType.UserType.GetType()); } else { return(false); } return(true); }
private static void addCustomValue(XElement parent, PropertyAuditingData propertyAuditingData, IValue value, ISimpleMapperBuilder mapper, bool insertable, bool key, System.Type typeOfUserImplementation) { if (parent != null) { var propMapping = MetadataTools.AddProperty(parent, propertyAuditingData.Name, typeOfUserImplementation.AssemblyQualifiedName, insertable, key); MetadataTools.AddColumns(propMapping, value.ColumnIterator.OfType <Column>()); var typeElement = new XElement(MetadataTools.CreateElementName("type"), new XAttribute("name", typeOfUserImplementation.AssemblyQualifiedName)); var simpleValue = value as SimpleValue; if (simpleValue != null) { var typeParameters = simpleValue.TypeParameters; if (typeParameters != null) { foreach (var paramKeyValue in typeParameters) { var typeParam = new XElement(MetadataTools.CreateElementName("param"), new XAttribute("name", paramKeyValue.Key), paramKeyValue.Value); typeElement.Add(typeParam); } } } propMapping.Add(typeElement); } if (mapper != null) { mapper.Add(propertyAuditingData.GetPropertyData()); } }
public void AddOneToOneNotOwning(PropertyAuditingData propertyAuditingData, IValue value, ICompositeMapperBuilder mapper, string entityName) { var propertyValue = (OneToOne)value; var owningReferencePropertyName = propertyValue.ReferencedPropertyName; // mappedBy var configuration = _mainGenerator.EntitiesConfigurations[entityName]; if (configuration == null) { throw new MappingException("An audited relation to a non-audited entity " + entityName + "!"); } var ownedIdMapping = configuration.IdMappingData; if (ownedIdMapping == null) { throw new MappingException("An audited relation to a non-audited entity " + entityName + "!"); } var lastPropertyPrefix = MappingTools.CreateToOneRelationPrefix(owningReferencePropertyName); var referencedEntityName = propertyValue.ReferencedEntityName; // Generating the id mapper for the relation var ownedIdMapper = ownedIdMapping.IdMapper.PrefixMappedProperties(lastPropertyPrefix); // Storing information about this relation _mainGenerator.EntitiesConfigurations[entityName].AddToOneNotOwningRelation( propertyAuditingData.Name, owningReferencePropertyName, referencedEntityName, ownedIdMapper, MappingTools.IgnoreNotFound(value)); // Adding mapper for the id var propertyData = propertyAuditingData.GetPropertyData(); mapper.AddComposite(propertyData, new OneToOneNotOwningMapper(entityName, referencedEntityName, owningReferencePropertyName, propertyData)); }
private void addModifiedFlagIfNeeded(XElement parent, PropertyAuditingData propertyAuditingData, bool processModifiedFlag) { if (processModifiedFlag && propertyAuditingData.UsingModifiedFlag) { MetadataTools.AddModifiedFlagProperty(parent, propertyAuditingData.Name, GlobalCfg.ModifiedFlagSuffix); } }
private void addValueInFirstPass(XElement parent, IValue value, ICompositeMapperBuilder currentMapper, string entityName, EntityXmlMappingData xmlMappingData, PropertyAuditingData propertyAuditingData, bool insertable, bool processModifiedFlag) { var type = value.Type; if (BasicMetadataGenerator.AddBasic(parent, propertyAuditingData, value, currentMapper, insertable, false)) { // The property was mapped by the basic generator. } else if (type is ComponentType) { componentMetadataGenerator.AddComponent(parent, propertyAuditingData, value, currentMapper, entityName, xmlMappingData, true, insertable); } else { if (!processedInSecondPass(type)) { // If we got here in the first pass, it means the basic mapper didn't map it, and none of the // above branches either. ThrowUnsupportedTypeException(type, entityName, propertyAuditingData.Name); } return; } addModifiedFlagIfNeeded(parent, propertyAuditingData, processModifiedFlag); }
/** * 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> * </ul> */ public void UpdateCalculatedFields() { foreach (KeyValuePair <PersistentClass, ClassAuditingData> classAuditingDataEntry in persistentClassToAuditingData) { PersistentClass pc = classAuditingDataEntry.Key; ClassAuditingData classAuditingData = classAuditingDataEntry.Value; foreach (String propertyName in classAuditingData.getPropertyNames()) { PropertyAuditingData propertyAuditingData = classAuditingData.getPropertyAuditingData(propertyName); // If a property had the @AuditMappedBy annotation, setting the referenced fields to be always insertable. if (propertyAuditingData.AuditMappedBy != null) { String referencedEntityName = MappingTools.getReferencedEntityName(pc.GetProperty(propertyName).Value); ClassAuditingData referencedClassAuditingData = entityNameToAuditingData[referencedEntityName]; ForcePropertyInsertable(referencedClassAuditingData, propertyAuditingData.AuditMappedBy, pc.EntityName, referencedEntityName); ForcePropertyInsertable(referencedClassAuditingData, propertyAuditingData.PositionMappedBy, pc.EntityName, referencedEntityName); } } } }
public void AddComponent(XElement parent, PropertyAuditingData propertyAuditingData, IValue value, ICompositeMapperBuilder mapper, string entityName, EntityXmlMappingData xmlMappingData, bool firstPass, bool insertable) { var propComponent = (Component)value; var componentMapper = mapper.AddComponent(propertyAuditingData.GetPropertyData(), propComponent.ComponentClassName); // The property auditing data must be for a component. var componentAuditingData = (ComponentAuditingData)propertyAuditingData; // Adding all properties of the component foreach (var property in propComponent.PropertyIterator) { var componentPropertyAuditingData = componentAuditingData.GetPropertyAuditingData(property.Name); // Checking if that property is audited if (componentPropertyAuditingData != null) { mainGenerator.AddValue(parent, property.Value, componentMapper, entityName, xmlMappingData, componentPropertyAuditingData, property.IsInsertable && insertable, firstPass, false); } } }
//@SuppressWarnings({"unchecked"}) public void AddComponent(XmlElement parent, PropertyAuditingData propertyAuditingData, IValue value, ICompositeMapperBuilder mapper, String entityName, EntityXmlMappingData xmlMappingData, bool firstPass) { Component prop_component = (Component)value; ICompositeMapperBuilder componentMapper = mapper.AddComponent(propertyAuditingData.getPropertyData(), prop_component.ComponentClassName); // The property auditing data must be for a component. ComponentAuditingData componentAuditingData = (ComponentAuditingData)propertyAuditingData; // Adding all properties of the component IEnumerator <Property> properties = (IEnumerator <Property>)prop_component.PropertyIterator.GetEnumerator(); while (properties.MoveNext()) { Property property = properties.Current; PropertyAuditingData componentPropertyAuditingData = componentAuditingData.getPropertyAuditingData(property.Name); // Checking if that property is audited if (componentPropertyAuditingData != null) { mainGenerator.AddValue(parent, property.Value, componentMapper, entityName, xmlMappingData, componentPropertyAuditingData, property.IsInsertable, firstPass); } } }
public void AddKeyManyToOne(XElement parent, PropertyAuditingData propertyAuditingData, IValue value, ISimpleMapperBuilder mapper) { var type = value.Type; var element = mapper == null? MetadataTools.AddKeyManyToOne(parent, propertyAuditingData.Name, type.ReturnedClass.AssemblyQualifiedName) : MetadataTools.AddManyToOne(parent, propertyAuditingData.Name, type.ReturnedClass.AssemblyQualifiedName, true, false); MetadataTools.AddColumns(element, value.ColumnIterator.OfType <Column>()); mapper?.Add(propertyAuditingData.GetPropertyData()); }
//@SuppressWarnings({"unchecked"}) public void AddToOne(XmlElement parent, PropertyAuditingData propertyAuditingData, IValue value, ICompositeMapperBuilder mapper, String entityName, bool insertable) { String referencedEntityName = ((ToOne)value).ReferencedEntityName; IdMappingData idMapping = mainGenerator.GetReferencedIdMappingData(entityName, referencedEntityName, propertyAuditingData, true); String lastPropertyPrefix = MappingTools.createToOneRelationPrefix(propertyAuditingData.Name); // Generating the id mapper for the relation IIdMapper relMapper = idMapping.IdMapper.PrefixMappedProperties(lastPropertyPrefix); // Storing information about this relation mainGenerator.EntitiesConfigurations[entityName].AddToOneRelation( propertyAuditingData.Name, referencedEntityName, relMapper, insertable); // 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. bool nonInsertableFake; if (!insertable && propertyAuditingData.ForceInsertable) { nonInsertableFake = true; insertable = true; } else { nonInsertableFake = false; } // Adding an element to the mapping corresponding to the references entity id's // Use OwnerDocument.ImportNode() instead of XmlNode.Clone(); XmlElement properties = (XmlElement)parent.OwnerDocument.ImportNode(idMapping.XmlRelationMapping, true); properties.SetAttribute("name", propertyAuditingData.Name); MetadataTools.PrefixNamesInPropertyElement(properties, lastPropertyPrefix, MetadataTools.GetColumnNameEnumerator((IEnumerator <ISelectable>)value.ColumnIterator.GetEnumerator()), false, insertable); parent.AppendChild(properties); // Adding mapper for the id PropertyData propertyData = propertyAuditingData.getPropertyData(); mapper.AddComposite(propertyData, new ToOneIdMapper(relMapper, propertyData, referencedEntityName, nonInsertableFake)); }
private static void addSimpleValue(XElement parent, PropertyAuditingData propertyAuditingData, IValue value, ISimpleMapperBuilder mapper, bool insertable, bool key) { if (parent != null) { var propMapping = MetadataTools.AddProperty(parent, propertyAuditingData.Name, value.Type.Name, propertyAuditingData.ForceInsertable || insertable, key, propertyAuditingData.AccessType); MetadataTools.AddColumns(propMapping, value.ColumnIterator.OfType <Column>()); } // A null mapper means that we only want to add xml mappings mapper?.Add(propertyAuditingData.GetPropertyData()); }
public void AddValue(XElement parent, IValue value, ICompositeMapperBuilder currentMapper, string entityName, EntityXmlMappingData xmlMappingData, PropertyAuditingData propertyAuditingData, bool insertable, bool firstPass, bool processModifiedFlag) { if (firstPass) { addValueInFirstPass(parent, value, currentMapper, entityName, xmlMappingData, propertyAuditingData, insertable, processModifiedFlag); } else { addValueInSecondPass(parent, value, currentMapper, entityName, xmlMappingData, propertyAuditingData, insertable, processModifiedFlag); } }
private bool CheckPropertiesAudited(IEnumerator<Property> properties, ClassAuditingData auditingData) { while (properties.MoveNext()) { Property property = properties.Current; String propertyName = property.Name; PropertyAuditingData propertyAuditingData = auditingData.getPropertyAuditingData(propertyName); if (propertyAuditingData == null) { return false; } } return true; }
private void AddSimpleValue(XmlElement parent, PropertyAuditingData propertyAuditingData, IValue value, ISimpleMapperBuilder mapper, bool insertable, bool key) { if (parent != null) { XmlElement prop_mapping = MetadataTools.AddProperty(parent, propertyAuditingData.Name, value.Type.Name, propertyAuditingData.ForceInsertable || insertable, key); MetadataTools.AddColumns(prop_mapping, (IEnumerator <ISelectable>)value.ColumnIterator.GetEnumerator()); } // A null mapper means that we only want to add xml mappings if (mapper != null) { mapper.Add(propertyAuditingData.getPropertyData()); } }
//@SuppressWarnings({"unchecked"}) private void AddProperties(XmlElement parent, IEnumerator<Property> properties, ICompositeMapperBuilder currentMapper, ClassAuditingData auditingData, String entityName, EntityXmlMappingData xmlMappingData, bool firstPass) { while (properties.MoveNext()) { Property property = properties.Current; String propertyName = property.Name; PropertyAuditingData propertyAuditingData = auditingData.getPropertyAuditingData(propertyName); if (propertyAuditingData != null) { AddValue(parent, property.Value, currentMapper, entityName, xmlMappingData, propertyAuditingData, property.IsInsertable, firstPass); } } }
public void AddOneToOnePrimaryKeyJoinColumn(PropertyAuditingData propertyAuditingData, IValue value, ICompositeMapperBuilder mapper, string entityName, bool insertable) { var referencedEntityName = ((ToOne)value).ReferencedEntityName; var idMapping = _mainGenerator.GetReferencedIdMappingData(entityName, referencedEntityName, propertyAuditingData, true); var lastPropertyPrefix = MappingTools.CreateToOneRelationPrefix(propertyAuditingData.Name); // Generating the id mapper for the relation var relMapper = idMapping.IdMapper.PrefixMappedProperties(lastPropertyPrefix); // Storing information about this relation _mainGenerator.EntitiesConfigurations[entityName].AddToOneRelation(propertyAuditingData.Name, referencedEntityName, relMapper, insertable, MappingTools.IgnoreNotFound(value)); // Adding mapper for the id var propertyData = propertyAuditingData.GetPropertyData(); mapper.AddComposite(propertyData, new OneToOnePrimaryKeyJoinColumnMapper(entityName, referencedEntityName, propertyData)); }
private void addValueInSecondPass(XElement parent, IValue value, ICompositeMapperBuilder currentMapper, string entityName, EntityXmlMappingData xmlMappingData, PropertyAuditingData propertyAuditingData, bool insertable, bool processModifiedFlag) { var type = value.Type; if (type is ComponentType) { componentMetadataGenerator.AddComponent(parent, propertyAuditingData, value, currentMapper, entityName, xmlMappingData, false, insertable); return; // mod flag field has been already generated in first pass } else if (type is ManyToOneType) { toOneRelationMetadataGenerator.AddToOne(parent, propertyAuditingData, value, currentMapper, entityName, insertable); } else if (type is OneToOneType) { var oneToOne = (OneToOne)value; if (oneToOne.ReferencedPropertyName != null && propertyAuditingData.RelationTargetAuditMode != RelationTargetAuditMode.NotAudited) { toOneRelationMetadataGenerator.AddOneToOneNotOwning(propertyAuditingData, value, currentMapper, entityName); } else { // @OneToOne relation marked with @PrimaryKeyJoinColumn toOneRelationMetadataGenerator.AddOneToOnePrimaryKeyJoinColumn(propertyAuditingData, value, currentMapper, entityName, insertable); } } else if (type is CollectionType) { var collectionMetadataGenerator = new CollectionMetadataGenerator(_metaDataStore, this, (Mapping.Collection)value, currentMapper, entityName, xmlMappingData, propertyAuditingData); collectionMetadataGenerator.AddCollection(); } else { return; } addModifiedFlagIfNeeded(parent, propertyAuditingData, processModifiedFlag); }
/** * @param mainGenerator Main generator, giving access to configuration and the basic mapper. * @param propertyValue Value of the collection, as mapped by Hibernate. * @param currentMapper Mapper, to which the appropriate {@link org.hibernate.envers.entities.mapper.PropertyMapper} * will be added. * @param referencingEntityName Name of the entity that owns this collection. * @param xmlMappingData In case this collection requires a middle table, additional mapping documents will * be created using this object. * @param propertyAuditingData Property auditing (meta-)data. Among other things, holds the name of the * property that references the collection in the referencing entity, the user data for middle (join) * table and the value of the <code>@MapKey</code> annotation, if there was one. */ public CollectionMetadataGenerator(AuditMetadataGenerator mainGenerator, Mapping.Collection propertyValue, ICompositeMapperBuilder currentMapper, String referencingEntityName, EntityXmlMappingData xmlMappingData, PropertyAuditingData propertyAuditingData) { this.mainGenerator = mainGenerator; this.propertyValue = propertyValue; this.currentMapper = currentMapper; this.referencingEntityName = referencingEntityName; this.xmlMappingData = xmlMappingData; this.propertyAuditingData = propertyAuditingData; this.propertyName = propertyAuditingData.Name; referencingEntityConfiguration = mainGenerator.EntitiesConfigurations[referencingEntityName]; if (referencingEntityConfiguration == null) { throw new MappingException("Unable to read auditing configuration for " + referencingEntityName + "!"); } referencedEntityName = MappingTools.getReferencedEntityName(propertyValue.Element); }
//@SuppressWarnings({"unchecked"}) public void AddOneToOneNotOwning(PropertyAuditingData propertyAuditingData, IValue value, ICompositeMapperBuilder mapper, String entityName) { OneToOne propertyValue = (OneToOne)value; String owningReferencePropertyName = propertyValue.ReferencedPropertyName; // mappedBy EntityConfiguration configuration = mainGenerator.EntitiesConfigurations[entityName]; if (configuration == null) { throw new MappingException("An audited relation to a non-audited entity " + entityName + "!"); } IdMappingData ownedIdMapping = configuration.IdMappingData; if (ownedIdMapping == null) { throw new MappingException("An audited relation to a non-audited entity " + entityName + "!"); } String lastPropertyPrefix = MappingTools.createToOneRelationPrefix(owningReferencePropertyName); String referencedEntityName = propertyValue.ReferencedEntityName; // Generating the id mapper for the relation IIdMapper ownedIdMapper = ownedIdMapping.IdMapper.PrefixMappedProperties(lastPropertyPrefix); // Storing information about this relation mainGenerator.EntitiesConfigurations[entityName].AddToOneNotOwningRelation( propertyAuditingData.Name, owningReferencePropertyName, referencedEntityName, ownedIdMapper); // Adding mapper for the id PropertyData propertyData = propertyAuditingData.getPropertyData(); mapper.AddComposite(propertyData, new OneToOneNotOwningMapper(owningReferencePropertyName, referencedEntityName, propertyData)); }
private void AddCustomValue(XmlElement parent, PropertyAuditingData propertyAuditingData, IValue value, ISimpleMapperBuilder mapper, bool insertable, bool key) { if (parent != null) { XmlElement prop_mapping = MetadataTools.AddProperty(parent, propertyAuditingData.Name, null, insertable, key); //CustomType propertyType = (CustomType) value.getType(); XmlElement type_mapping = parent.OwnerDocument.CreateElement("type"); prop_mapping.AppendChild(type_mapping); type_mapping.SetAttribute("name", value.GetType().Name); if (value is SimpleValue) { IDictionary <string, string> typeParameters = ((SimpleValue)value).TypeParameters; if (typeParameters != null) { foreach (KeyValuePair <string, string> paramKeyValue in typeParameters) { XmlElement type_param = parent.OwnerDocument.CreateElement("param"); type_param.SetAttribute("name", (String)paramKeyValue.Key); type_param["name"].Value = paramKeyValue.Value; } } } MetadataTools.AddColumns(prop_mapping, (IEnumerator <ISelectable>)value.ColumnIterator); } if (mapper != null) { mapper.Add(propertyAuditingData.getPropertyData()); } }
//@SuppressWarnings({"unchecked"}) public void AddValue(XmlElement parent, IValue value, ICompositeMapperBuilder currentMapper, String entityName, EntityXmlMappingData xmlMappingData, PropertyAuditingData propertyAuditingData, bool insertable, bool firstPass) { IType type = value.Type; // only first pass if (firstPass) { if (BasicMetadataGenerator.AddBasic(parent, propertyAuditingData, value, currentMapper, insertable, false)) { // The property was mapped by the basic generator. return; } } if (type is ComponentType) { // both passes componentMetadataGenerator.AddComponent(parent, propertyAuditingData, value, currentMapper, entityName, xmlMappingData, firstPass); } else if (type is ManyToOneType) { // only second pass if (!firstPass) { toOneRelationMetadataGenerator.AddToOne(parent, propertyAuditingData, value, currentMapper, entityName, insertable); } } else if (type is OneToOneType) { // only second pass if (!firstPass) { toOneRelationMetadataGenerator.AddOneToOneNotOwning(propertyAuditingData, value, currentMapper, entityName); } } else if (type is CollectionType) { // only second pass if (!firstPass) { CollectionMetadataGenerator collectionMetadataGenerator = new CollectionMetadataGenerator(this, (Mapping.Collection)value, currentMapper, entityName, xmlMappingData, propertyAuditingData); collectionMetadataGenerator.AddCollection(); } } else { if (firstPass) { // If we got here in the first pass, it means the basic mapper didn't map it, and none of the // above branches either. ThrowUnsupportedTypeException(type, entityName, propertyAuditingData.Name); } } }
public void AddToOne(XElement parent, PropertyAuditingData propertyAuditingData, IValue value, ICompositeMapperBuilder mapper, string entityName, bool insertable) { var referencedEntityName = ((ToOne)value).ReferencedEntityName; var idMapping = _mainGenerator.GetReferencedIdMappingData(entityName, referencedEntityName, propertyAuditingData, true); var lastPropertyPrefix = MappingTools.CreateToOneRelationPrefix(propertyAuditingData.Name); // Generating the id mapper for the relation var relMapper = idMapping.IdMapper.PrefixMappedProperties(lastPropertyPrefix); // Storing information about this relation _mainGenerator.EntitiesConfigurations[entityName].AddToOneRelation( propertyAuditingData.Name, 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. bool nonInsertableFake; if (!insertable && propertyAuditingData.ForceInsertable) { nonInsertableFake = true; insertable = true; } else { nonInsertableFake = false; } // Adding an element to the mapping corresponding to the references entity id's var properties = new XElement(idMapping.XmlRelationMapping); properties.Add(new XAttribute("name", propertyAuditingData.Name)); MetadataTools.PrefixNamesInPropertyElement(properties, lastPropertyPrefix, MetadataTools.GetColumnNameEnumerator(value.ColumnIterator), false, insertable, propertyAuditingData.AccessType); // Extracting related id properties from properties tag var firstJoin = firstJoinElement(parent); foreach (var element in properties.Elements()) { if (firstJoin == null) { parent.Add(element); } else { firstJoin.AddBeforeSelf(element); } } // Adding mapper for the id var propertyData = propertyAuditingData.GetPropertyData(); mapper.AddComposite(propertyData, new ToOneIdMapper(relMapper, propertyData, referencedEntityName, nonInsertableFake)); }