@SuppressWarnings({"unchecked"}) private boolean addIdProperties( Element parent, Iterator<Property> properties, SimpleMapperBuilder mapper, boolean key, boolean audited) { while (properties.hasNext()) { Property property = properties.next(); Type propertyType = property.getType(); if (!"_identifierMapper".equals(property.getName())) { // Last but one parameter: ids are always insertable boolean added = mainGenerator .getBasicMetadataGenerator() .addBasic( parent, getIdPersistentPropertyAuditingData(property), property.getValue(), mapper, true, key); if (!added) { // If the entity is audited, and a non-supported id component is used, throwing an // exception. // If the entity is not audited, then we simply don't support this entity, even in // target relation mode not audited. if (audited) { throw new MappingException("Type not supported: " + propertyType.getClass().getName()); } else { return false; } } } } return true; }
/** * @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( Value value, Element xmlMapping, QueryGeneratorBuilder queryGeneratorBuilder, String prefix, JoinColumn[] joinColumns) { Type type = value.getType(); if (type instanceof 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.getColumnNameIterator(joinColumns) : MetadataTools.getColumnNameIterator(value.getColumnIterator()), 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.getCurrentIndex()); } else { // Last but one parameter: collection components are always insertable boolean mapped = mainGenerator .getBasicMetadataGenerator() .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.getVerEntCfg(), prefix), 0); } else { mainGenerator.throwUnsupportedTypeException(type, referencingEntityName, propertyName); // Impossible to get here. throw new AssertionError(); } } }
@SuppressWarnings({"unchecked"}) IdMappingData addId(PersistentClass pc, boolean audited) { // Xml mapping which will be used for relations Element rel_id_mapping = new DefaultElement("properties"); // Xml mapping which will be used for the primary key of the versions table Element orig_id_mapping = new DefaultElement("composite-id"); Property id_prop = pc.getIdentifierProperty(); Component id_mapper = pc.getIdentifierMapper(); // Checking if the id mapping is supported if (id_mapper == null && id_prop == null) { return null; } SimpleIdMapperBuilder mapper; if (id_mapper != null) { // Multiple id mapper = new MultipleIdMapper(((Component) pc.getIdentifier()).getComponentClassName()); if (!addIdProperties( rel_id_mapping, (Iterator<Property>) id_mapper.getPropertyIterator(), mapper, false, audited)) { return null; } // null mapper - the mapping where already added the first time, now we only want to generate // the xml if (!addIdProperties( orig_id_mapping, (Iterator<Property>) id_mapper.getPropertyIterator(), null, true, audited)) { return null; } } else if (id_prop.isComposite()) { // Embedded id Component id_component = (Component) id_prop.getValue(); mapper = new EmbeddedIdMapper(getIdPropertyData(id_prop), id_component.getComponentClassName()); if (!addIdProperties( rel_id_mapping, (Iterator<Property>) id_component.getPropertyIterator(), mapper, false, audited)) { return null; } // null mapper - the mapping where already added the first time, now we only want to generate // the xml if (!addIdProperties( orig_id_mapping, (Iterator<Property>) id_component.getPropertyIterator(), null, true, audited)) { return null; } } else { // Single id mapper = new SingleIdMapper(); // Last but one parameter: ids are always insertable mainGenerator .getBasicMetadataGenerator() .addBasic( rel_id_mapping, getIdPersistentPropertyAuditingData(id_prop), id_prop.getValue(), mapper, true, false); // null mapper - the mapping where already added the first time, now we only want to generate // the xml mainGenerator .getBasicMetadataGenerator() .addBasic( orig_id_mapping, getIdPersistentPropertyAuditingData(id_prop), id_prop.getValue(), null, true, true); } orig_id_mapping.addAttribute("name", mainGenerator.getVerEntCfg().getOriginalIdPropName()); // Adding a relation to the revision entity (effectively: the "revision number" property) mainGenerator.addRevisionInfoRelation(orig_id_mapping); return new IdMappingData(mapper, orig_id_mapping, rel_id_mapping); }