예제 #1
0
 protected void assignInstanceValuesFromResult(
     T instance,
     List<PropertyConfig> instancePropertyConfigs,
     DatabaseResults results,
     Map<String, Integer> colPosMap,
     Object id,
     Boolean foreignCollections,
     ObjectCache objectCache)
     throws SQLException {
   for (PropertyConfig propertyConfig : instancePropertyConfigs) {
     if (propertyConfig.isForeignCollection()) {
       foreignCollections = true;
     } else {
       Object val = propertyConfig.resultToJava(results, colPosMap);
       /*
        * This is pretty subtle. We introduced multiple foreign fields to the same type which use the {@link
        * ForeignCollectionField} foreignColumnName field. The bug that was created was that all the fields
        * were then set with the parent class. Only the fields that have a matching id value should be set to
        * the parent. We had to add the val.equals logic.
        */
       if (val != null
           && parent != null
           && propertyConfig.getField().getType() == parent.getClass()
           && val.equals(parentId)) {
         propertyConfig.assignField(instance, parent, true, objectCache);
       } else {
         propertyConfig.assignField(instance, val, false, objectCache);
       }
       if (propertyConfig == idField) {
         id = val;
       }
     }
   }
 }
예제 #2
0
  public T mapRow(DatabaseResults results) throws SQLException {
    Map<String, Integer> colPosMap;
    if (columnPositions == null) {
      colPosMap = new HashMap<String, Integer>();
    } else {
      colPosMap = columnPositions;
    }

    ObjectCache objectCache = results.getObjectCache();
    Object id = null;
    if (objectCache != null) {
      id = idField.resultToJava(results, colPosMap);
      T cachedInstance = objectCache.get(entityConfig, id);
      if (cachedInstance != null) {
        // if we have a cached instance for this id then return it
        return cachedInstance;
      }
    }

    // create our instance
    List<PropertyConfig> instancePropertyConfigs = new ArrayList<>();
    T instance =
        createInstanceForResults(
            entityConfig, results, colPosMap, instancePropertyConfigs, resultsPropertyConfigs);

    if (objectCache != null && id != null) {
      // why not adding instance already here to cache? Avoids multiple retrievals on (deep)
      // recursive dependencies on its fields
      objectCache.put(
          (Class<T>) instance.getClass(),
          id,
          instance); // don't use clazz variable here as for tables with inheritance this might be
                     // wrong (it might only be the parent class)
    }

    // populate its fields
    Boolean foreignCollections = false;

    for (PropertyConfig propertyConfig : instancePropertyConfigs) {
      if (propertyConfig.isForeignCollection()) {
        foreignCollections = true;
      } else {
        Object val = propertyConfig.resultToJava(results, colPosMap);
        /*
         * This is pretty subtle. We introduced multiple foreign fields to the same type which use the {@link
         * ForeignCollectionField} foreignColumnName field. The bug that was created was that all the fields
         * were then set with the parent class. Only the fields that have a matching id value should be set to
         * the parent. We had to add the val.equals logic.
         */
        if (val != null
            && parent != null
            && propertyConfig.getType() == parent.getClass()
            && val.equals(parentId)) {
          propertyConfig.assignField(instance, parent, true, objectCache);
        } else {
          propertyConfig.assignField(instance, val, false, objectCache);
        }
        if (propertyConfig == idField) {
          id = val;
        }
      }
    }

    // if we have a cache and we have an id then add it to the cache
    //    if (objectCache != null && id != null) { // for ManyToMany collections it is of great
    // importance that instance will be cached already here, before ForeignCollections will be built
    //      objectCache.put(clazz, id, instance);
    //    }

    if (foreignCollections) {
      // go back and initialize any foreign collections
      for (PropertyConfig propertyConfig : instancePropertyConfigs) {
        if (propertyConfig.isForeignCollection()) {
          Collection collection =
              propertyConfig.buildForeignCollection(
                  instance, id); // cda: implement against interfaces, not implementations
          if (collection != null) {
            propertyConfig.assignField(instance, collection, false, objectCache);
          }
        }
      }
    }

    if (columnPositions == null) {
      columnPositions = colPosMap;
    }

    entityConfig.invokePostLoadLifeCycleMethod(instance);

    return instance;
  }