private MiddleComponentData addIndex( Element middleEntityXml, QueryGeneratorBuilder queryGeneratorBuilder) { if (propertyValue instanceof IndexedCollection) { IndexedCollection indexedValue = (IndexedCollection) propertyValue; String mapKey = propertyAuditingData.getMapKey(); if (mapKey == null) { // This entity doesn't specify a javax.persistence.MapKey. Mapping it to the middle entity. return addValueToMiddleTable( indexedValue.getIndex(), middleEntityXml, queryGeneratorBuilder, "mapkey", null); } else { IdMappingData referencedIdMapping = mainGenerator.getEntitiesConfigurations().get(referencedEntityName).getIdMappingData(); int currentIndex = queryGeneratorBuilder == null ? 0 : queryGeneratorBuilder.getCurrentIndex(); if ("".equals(mapKey)) { // The key of the map is the id of the entity. return new MiddleComponentData( new MiddleMapKeyIdComponentMapper( mainGenerator.getVerEntCfg(), referencedIdMapping.getIdMapper()), currentIndex); } else { // The key of the map is a property of the entity. return new MiddleComponentData( new MiddleMapKeyPropertyComponentMapper(mapKey, propertyAuditingData.getAccessType()), currentIndex); } } } else { // No index - creating a dummy mapper. return new MiddleComponentData(new MiddleDummyComponentMapper(), 0); } }
/** * @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(); } } }