예제 #1
0
        //@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));
        }
예제 #2
0
        //@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));
        }
예제 #3
0
        private void AddOneToManyAttached(bool fakeOneToManyBidirectional)
        {
            //throw new NotImplementedException();

            log.Debug("Adding audit mapping for property " + referencingEntityName + "." + propertyName +
                      ": one-to-many collection, using a join column on the referenced entity.");

            String mappedBy = GetMappedBy(propertyValue);

            IdMappingData referencedIdMapping = mainGenerator.GetReferencedIdMappingData(referencingEntityName,
                                                                                         referencedEntityName, propertyAuditingData, false);
            IdMappingData referencingIdMapping = referencingEntityConfiguration.IdMappingData;

            // Generating the id mappers data for the referencing side of the relation.
            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).
            MiddleIdData referencedIdData = CreateMiddleIdData(referencedIdMapping,
                                                               null, referencedEntityName);

            // Generating the element mapping.
            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.
            IRelationQueryGenerator queryGenerator = new OneAuditEntityQueryGenerator(mainGenerator.GlobalCfg,
                                                                                      mainGenerator.VerEntCfg, referencingIdData, referencedEntityName,
                                                                                      referencedIdMapping.IdMapper);

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

            IPropertyMapper fakeBidirectionalRelationMapper;
            IPropertyMapper fakeBidirectionalRelationIndexMapper;

            if (fakeOneToManyBidirectional)
            {
                // 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).
                String auditMappedBy = propertyAuditingData.AuditMappedBy;

                // Creating a prefixed relation mapper.
                IIdMapper relMapper = referencingIdMapping.IdMapper.PrefixMappedProperties(
                    MappingTools.createToOneRelationPrefix(auditMappedBy));

                fakeBidirectionalRelationMapper = new ToOneIdMapper(
                    relMapper,
                    // The mapper will only be used to map from entity to map, so no need to provide other details
                    // when constructing the PropertyData.
                    new PropertyData(auditMappedBy, null, null, ModificationStore._NULL),
                    referencedEntityName, false);

                // Checking if there's an index defined. If so, adding a mapper for it.
                if (propertyAuditingData.PositionMappedBy != null)
                {
                    String positionMappedBy = propertyAuditingData.PositionMappedBy;
                    fakeBidirectionalRelationIndexMapper = new SinglePropertyMapper(new PropertyData(positionMappedBy, null, null, ModificationStore._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.PrefixedMapper, fakeBidirectionalRelationMapper,
                                                                      fakeBidirectionalRelationIndexMapper);
        }