/** * 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); } } } }
/** * * @param value Value, which should be mapped to the middle-table, either as a relation to another entity, * or as a simple value. * @param xmlMapping If not <code>null</code>, xml mapping for this value is added to this element. * @param queryGeneratorBuilder In case <code>value</code> is a relation to another entity, information about it * should be added to the given. * @param prefix Prefix for proeprty names of related entities identifiers. * @param joinColumns Names of columns to use in the xml mapping, if this array isn't null and has any elements. * @return Data for mapping this component. */ //@SuppressWarnings({"unchecked"}) private MiddleComponentData AddValueToMiddleTable(IValue value, XmlElement xmlMapping, QueryGeneratorBuilder queryGeneratorBuilder, String prefix, JoinColumnAttribute[] joinColumns) { IType type = value.Type; if (type is ManyToOneType) { String prefixRelated = prefix + "_"; String referencedEntityName = MappingTools.getReferencedEntityName(value); IdMappingData referencedIdMapping = mainGenerator.GetReferencedIdMappingData(referencingEntityName, referencedEntityName, propertyAuditingData, true); // Adding related-entity (in this case: the referenced entities id) id mapping to the xml only if the // relation isn't inverse (so when <code>xmlMapping</code> is not null). if (xmlMapping != null) { AddRelatedToXmlMapping(xmlMapping, prefixRelated, joinColumns != null && joinColumns.Length > 0 ? MetadataTools.GetColumnNameEnumerator(joinColumns) : MetadataTools.GetColumnNameEnumerator(value.ColumnIterator.GetEnumerator()), referencedIdMapping); } // Storing the id data of the referenced entity: original mapper, prefixed mapper and entity name. MiddleIdData referencedIdData = CreateMiddleIdData(referencedIdMapping, prefixRelated, referencedEntityName); // And adding it to the generator builder. queryGeneratorBuilder.AddRelation(referencedIdData); return(new MiddleComponentData(new MiddleRelatedComponentMapper(referencedIdData), queryGeneratorBuilder.CurrentIndex)); } else { // Last but one parameter: collection components are always insertable bool mapped = mainGenerator.BasicMetadataGenerator.AddBasic(xmlMapping, new PropertyAuditingData(prefix, "field", ModificationStore.FULL, RelationTargetAuditMode.AUDITED, null, null, false), value, null, true, true); if (mapped) { // Simple values are always stored in the first item of the array returned by the query generator. return(new MiddleComponentData(new MiddleSimpleComponentMapper(mainGenerator.VerEntCfg, prefix), 0)); } else { mainGenerator.ThrowUnsupportedTypeException(type, referencingEntityName, propertyName); // Impossible to get here. throw new AssertionFailure(); } } }
private String GetMiddleTableName(Mapping.Collection value, String entityName) { // We check how Hibernate maps the collection. if (value.Element is OneToMany && !value.IsInverse) { // This must be a @JoinColumn+@OneToMany mapping. Generating the table name, as Hibernate doesn't use a // middle table for mapping this relation. String refEntName = MappingTools.getReferencedEntityName(value.Element); return(entityName.Substring(entityName.LastIndexOf(".") + 1) + "_" + refEntName.Substring(refEntName.LastIndexOf(".") + 1)); } else { // Hibernate uses a middle table for mapping this relation, so we get it's name directly. return(value.CollectionTable.Name); } }
/** * @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); }