public OneToManyPersister(
     Collection collection,
     CollectionRegionAccessStrategy cacheAccessStrategy,
     Configuration cfg,
     SessionFactoryImplementor factory)
     throws MappingException, CacheException {
   super(collection, cacheAccessStrategy, cfg, factory);
   cascadeDeleteEnabled =
       collection.getKey().isCascadeDeleteEnabled()
           && factory.getDialect().supportsCascadeDelete();
   keyIsNullable = collection.getKey().isNullable();
   keyIsUpdateable = collection.getKey().isUpdateable();
 }
  @SuppressWarnings({"unchecked"})
  private String searchMappedBy(PersistentClass referencedClass, Collection collectionValue) {
    Iterator<Property> assocClassProps = referencedClass.getPropertyIterator();
    while (assocClassProps.hasNext()) {
      Property property = assocClassProps.next();

      if (Tools.iteratorsContentEqual(
          property.getValue().getColumnIterator(), collectionValue.getKey().getColumnIterator())) {
        return property.getName();
      }
    }
    return null;
  }
Example #3
0
  public void doSecondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas)
      throws MappingException {
    if (log.isDebugEnabled()) log.debug("Second pass for collection: " + collection.getRole());

    secondPass(persistentClasses, inheritedMetas);
    collection.createAllKeys();

    if (log.isDebugEnabled()) {
      String msg = "Mapped collection key: " + columns(collection.getKey());
      if (collection.isIndexed())
        msg += ", index: " + columns(((IndexedCollection) collection).getIndex());
      if (collection.isOneToMany()) {
        msg += ", one-to-many: " + ((OneToMany) collection.getElement()).getReferencedEntityName();
      } else {
        msg += ", element: " + columns(collection.getElement());
      }
      log.debug(msg);
    }
  }
  public void doSecondPass(java.util.Map persistentClasses) throws MappingException {
    if (log.isDebugEnabled()) log.debug("Second pass for collection: " + collection.getRole());

    secondPass(
        persistentClasses,
        localInheritedMetas); // using local since the inheritedMetas at this point is not the
                              // correct map since it is always the empty map
    collection.createAllKeys();

    if (log.isDebugEnabled()) {
      String msg = "Mapped collection key: " + columns(collection.getKey());
      if (collection.isIndexed())
        msg += ", index: " + columns(((IndexedCollection) collection).getIndex());
      if (collection.isOneToMany()) {
        msg += ", one-to-many: " + ((OneToMany) collection.getElement()).getReferencedEntityName();
      } else {
        msg += ", element: " + columns(collection.getElement());
      }
      log.debug(msg);
    }
  }
  @SuppressWarnings({"unchecked"})
  private void addWithMiddleTable() {

    LOG.debugf(
        "Adding audit mapping for property %s.%s: collection with a join table",
        referencingEntityName, propertyName);

    // Generating the name of the middle table
    String auditMiddleTableName;
    String auditMiddleEntityName;
    if (!StringTools.isEmpty(propertyAuditingData.getJoinTable().name())) {
      auditMiddleTableName = propertyAuditingData.getJoinTable().name();
      auditMiddleEntityName = propertyAuditingData.getJoinTable().name();
    } else {
      String middleTableName = getMiddleTableName(propertyValue, referencingEntityName);
      auditMiddleTableName = mainGenerator.getVerEntCfg().getAuditTableName(null, middleTableName);
      auditMiddleEntityName = mainGenerator.getVerEntCfg().getAuditEntityName(middleTableName);
    }

    LOG.debugf("Using join table name: %s", 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.
    Element middleEntityXml;
    if (!propertyValue.isInverse()) {
      // Generating a unique middle entity name
      auditMiddleEntityName =
          mainGenerator.getAuditEntityNameRegister().createUnique(auditMiddleEntityName);

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

      middleEntityXml =
          createMiddleEntityXml(
              auditMiddleTableName, auditMiddleEntityName, propertyValue.getWhere());
    } 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.getIdMappingData();

    // 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.getCollectionTable(),
              mainGenerator.getCfg().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.getGlobalCfg(),
            mainGenerator.getVerEntCfg(),
            mainGenerator.getAuditStrategy(),
            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.getColumnNameIterator(propertyValue.getKey().getColumnIterator()),
          referencingIdMapping);
    }

    // ******
    // Generating the element mapping.
    // ******
    MiddleComponentData elementComponentData =
        addValueToMiddleTable(
            propertyValue.getElement(),
            middleEntityXml,
            queryGeneratorBuilder,
            referencedPrefix,
            propertyAuditingData.getJoinTable().inverseJoinColumns());

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

    // ******
    // Generating the property mapper.
    // ******
    // Building the query generator.
    RelationQueryGenerator queryGenerator =
        queryGeneratorBuilder.build(elementComponentData, indexComponentData);

    // Creating common data
    CommonCollectionMapperData commonCollectionMapperData =
        new CommonCollectionMapperData(
            mainGenerator.getVerEntCfg(),
            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);
  }