Example #1
0
        private void addWithMiddleTable()
        {
            log.Debug("Adding audit mapping for property {0}. {1}" +
                      ": collection with a join table.", _referencingEntityName, _propertyName);

            // Generating the name of the middle table
            string auditMiddleTableName;
            string auditMiddleEntityName;

            if (!string.IsNullOrEmpty(_propertyAuditingData.JoinTable.TableName))
            {
                auditMiddleTableName  = _propertyAuditingData.JoinTable.TableName;
                auditMiddleEntityName = _propertyAuditingData.JoinTable.TableName;
            }
            else
            {
                // We check how Hibernate maps the collection.
                if (_propertyValue.Element is OneToMany && !_propertyValue.IsInverse)
                {
                    // This must be a @JoinColumn+@OneToMany mapping. Generating the table name, as Hibernate doesn't use a
                    // middle table for mapping this relation.
                    var referencingPersistentClass = _mainGenerator.Cfg.GetClassMapping(_referencingEntityName);
                    var referencedPersistentClass  = _mainGenerator.Cfg.GetClassMapping(_referencedEntityName);
                    auditMiddleTableName  = _mainGenerator.VerEntCfg.UnidirectionOneToManyTableName(referencingPersistentClass, referencedPersistentClass);
                    auditMiddleEntityName = _mainGenerator.VerEntCfg.GetAuditEntityName(_referencingEntityName, _referencedEntityName);
                }
                else
                {
                    auditMiddleTableName  = _mainGenerator.VerEntCfg.CollectionTableName(_propertyValue);
                    auditMiddleEntityName = _mainGenerator.VerEntCfg.GetAuditEntityName(_propertyValue.CollectionTable.Name);
                }
            }

            log.Debug("Using join table name: {0}", auditMiddleTableName);

            // Generating the XML mapping for the middle entity, only if the relation isn't inverse.
            // If the relation is inverse, will be later checked by comparing middleEntityXml with null.
            XElement middleEntityXml;

            if (!_propertyValue.IsInverse)
            {
                // Generating a unique middle entity name
                auditMiddleEntityName = _mainGenerator.AuditEntityNameRegister.CreateUnique(auditMiddleEntityName);

                // Registering the generated name
                _mainGenerator.AuditEntityNameRegister.Register(auditMiddleEntityName);

                middleEntityXml = createMiddleEntityXml(auditMiddleTableName, auditMiddleEntityName, _propertyValue.Where);
            }
            else
            {
                middleEntityXml = null;
            }

            // ******
            // Generating the mapping for the referencing entity (it must be an entity).
            // ******
            // Getting the id-mapping data of the referencing entity (the entity that "owns" this collection).
            var referencingIdMapping = _referencingEntityConfiguration.IdMappingData;

            // Only valid for an inverse relation; null otherwise.
            string mappedBy;

            // The referencing prefix is always for a related entity. So it has always the "_" at the end added.
            string referencingPrefixRelated;
            string referencedPrefix;

            if (_propertyValue.IsInverse)
            {
                // If the relation is inverse, then referencedEntityName is not null.
                mappedBy = getMappedBy(_propertyValue.CollectionTable, _mainGenerator.Cfg.GetClassMapping(_referencedEntityName));

                referencingPrefixRelated = mappedBy + "_";
                referencedPrefix         = StringTools.GetLastComponent(_referencedEntityName);
            }
            else
            {
                mappedBy = null;

                referencingPrefixRelated = StringTools.GetLastComponent(_referencingEntityName) + "_";
                referencedPrefix         = _referencedEntityName == null ? "element" : _propertyName;
            }

            // Storing the id data of the referencing entity: original mapper, prefixed mapper and entity name.
            var referencingIdData = createMiddleIdData(referencingIdMapping, referencingPrefixRelated, _referencingEntityName);

            // Creating a query generator builder, to which additional id data will be added, in case this collection
            // references some entities (either from the element or index). At the end, this will be used to build
            // a query generator to read the raw data collection from the middle table.
            var queryGeneratorBuilder = new QueryGeneratorBuilder(_mainGenerator.VerEntCfg, _mainGenerator.GlobalCfg.AuditStrategy, referencingIdData, auditMiddleEntityName, isEmbeddableElementType());

            // Adding the XML mapping for the referencing entity, if the relation isn't inverse.
            if (middleEntityXml != null)
            {
                // Adding related-entity (in this case: the referencing's entity id) id mapping to the xml.
                addRelatedToXmlMapping(middleEntityXml, referencingPrefixRelated,
                                       MetadataTools.GetColumnNameEnumerator(_propertyValue.Key.ColumnIterator),
                                       referencingIdMapping);
            }

            // ******
            // Generating the element mapping.
            // ******
            var elementComponentData = addValueToMiddleTable(_propertyValue.Element, middleEntityXml,
                                                             queryGeneratorBuilder, referencedPrefix, _propertyAuditingData.JoinTable.InverseJoinColumns);

            // ******
            // Generating the index mapping, if an index exists.
            // ******
            var indexComponentData = addIndex(middleEntityXml, queryGeneratorBuilder);

            // ******
            // Generating the property mapper.
            // ******
            // Building the query generator.
            var queryGenerator = queryGeneratorBuilder.Build(new Collection <MiddleComponentData> {
                elementComponentData, indexComponentData
            });

            // Creating common data
            var commonCollectionMapperData = new CommonCollectionMapperData(
                _mainGenerator.VerEntCfg, auditMiddleEntityName,
                _propertyAuditingData.GetPropertyData(),
                referencingIdData, queryGenerator);

            // Checking the type of the collection and adding an appropriate mapper.
            addMapper(commonCollectionMapperData, elementComponentData, indexComponentData);

            // ******
            // Storing information about this relation.
            // ******
            storeMiddleEntityRelationInformation(mappedBy);
        }
Example #2
0
        private void AddWithMiddleTable()
        {
            log.Debug("Adding audit mapping for property " + referencingEntityName + "." + propertyName +
                      ": collection with a join table.");

            // Generating the name of the middle table
            String auditMiddleTableName;
            String auditMiddleEntityName;

            if (!String.IsNullOrEmpty(propertyAuditingData.JoinTable.Name))
            {
                auditMiddleTableName  = propertyAuditingData.JoinTable.Name;
                auditMiddleEntityName = propertyAuditingData.JoinTable.Name;
            }
            else
            {
                String middleTableName = GetMiddleTableName(propertyValue, referencingEntityName);
                auditMiddleTableName  = mainGenerator.VerEntCfg.GetAuditTableName(null, middleTableName);
                auditMiddleEntityName = mainGenerator.VerEntCfg.GetAuditEntityName(middleTableName);
            }

            log.Debug("Using join table name: " + auditMiddleTableName);

            // Generating the XML mapping for the middle entity, only if the relation isn't inverse.
            // If the relation is inverse, will be later checked by comparing middleEntityXml with null.
            XmlElement middleEntityXml;

            if (!propertyValue.IsInverse)
            {
                // Generating a unique middle entity name
                auditMiddleEntityName = mainGenerator.AuditEntityNameRegister.createUnique(auditMiddleEntityName);

                // Registering the generated name
                mainGenerator.AuditEntityNameRegister.register(auditMiddleEntityName);

                middleEntityXml = CreateMiddleEntityXml(auditMiddleTableName, auditMiddleEntityName, propertyValue.Where);
            }
            else
            {
                middleEntityXml = null;
            }

            // ******
            // Generating the mapping for the referencing entity (it must be an entity).
            // ******
            // Getting the id-mapping data of the referencing entity (the entity that "owns" this collection).
            IdMappingData referencingIdMapping = referencingEntityConfiguration.IdMappingData;

            // Only valid for an inverse relation; null otherwise.
            String mappedBy;

            // The referencing prefix is always for a related entity. So it has always the "_" at the end added.
            String referencingPrefixRelated;
            String referencedPrefix;

            if (propertyValue.IsInverse)
            {
                // If the relation is inverse, then referencedEntityName is not null.
                mappedBy = GetMappedBy(propertyValue.CollectionTable, mainGenerator.Cfg.GetClassMapping(referencedEntityName));

                referencingPrefixRelated = mappedBy + "_";
                referencedPrefix         = StringTools.GetLastComponent(referencedEntityName);
            }
            else
            {
                mappedBy = null;

                referencingPrefixRelated = StringTools.GetLastComponent(referencingEntityName) + "_";
                referencedPrefix         = referencedEntityName == null ? "element" : propertyName;
            }

            // Storing the id data of the referencing entity: original mapper, prefixed mapper and entity name.
            MiddleIdData referencingIdData = CreateMiddleIdData(referencingIdMapping,
                                                                referencingPrefixRelated, referencingEntityName);

            // Creating a query generator builder, to which additional id data will be added, in case this collection
            // references some entities (either from the element or index). At the end, this will be used to build
            // a query generator to read the raw data collection from the middle table.
            QueryGeneratorBuilder queryGeneratorBuilder = new QueryGeneratorBuilder(mainGenerator.GlobalCfg,
                                                                                    mainGenerator.VerEntCfg, referencingIdData, auditMiddleEntityName);

            // Adding the XML mapping for the referencing entity, if the relation isn't inverse.
            if (middleEntityXml != null)
            {
                // Adding related-entity (in this case: the referencing's entity id) id mapping to the xml.
                AddRelatedToXmlMapping(middleEntityXml, referencingPrefixRelated,
                                       MetadataTools.GetColumnNameEnumerator(propertyValue.Key.ColumnIterator.GetEnumerator()),
                                       referencingIdMapping);
            }

            // ******
            // Generating the element mapping.
            // ******
            MiddleComponentData elementComponentData = AddValueToMiddleTable(propertyValue.Element, middleEntityXml,
                                                                             queryGeneratorBuilder, referencedPrefix, propertyAuditingData.JoinTable.InverseJoinColumns);

            // ******
            // Generating the index mapping, if an index exists.
            // ******
            MiddleComponentData indexComponentData = AddIndex(middleEntityXml, queryGeneratorBuilder);

            // ******
            // Generating the property mapper.
            // ******
            // Building the query generator.
            IRelationQueryGenerator queryGenerator = queryGeneratorBuilder.Build(new Collection <MiddleComponentData> {
                elementComponentData, indexComponentData
            });

            // Creating common data
            CommonCollectionMapperData commonCollectionMapperData = new CommonCollectionMapperData(
                mainGenerator.VerEntCfg, auditMiddleEntityName,
                propertyAuditingData.getPropertyData(),
                referencingIdData, queryGenerator);

            // Checking the type of the collection and adding an appropriate mapper.
            AddMapper(commonCollectionMapperData, elementComponentData, indexComponentData);

            // ******
            // Storing information about this relation.
            // ******
            StoreMiddleEntityRelationInformation(mappedBy);
        }