예제 #1
0
  protected T createInstanceForResults(
      EntityConfig<T, ID> entityConfig,
      DatabaseResults results,
      Map<String, Integer> columnPositions,
      List<PropertyConfig> instancePropertyConfigs,
      PropertyConfig[] resultsPropertyConfigs)
      throws SQLException {
    if (entityConfig.getInheritance() != InheritanceType.JOINED) {
      instancePropertyConfigs.addAll(Arrays.asList(resultsPropertyConfigs));
      return this.entityConfig.createObject();
    } else {
      //      if(tableInfo.getChildTableInfos().size() == 0) { // class lowest in inheritance
      // hierarchy
      //        return tableInfo.createObject();
      //      }

      JoinedEntityConfig joinedTableInfo =
          (JoinedEntityConfig) entityConfig.getInheritanceTopLevelEntityConfig();
      String discriminatorColumnName =
          joinedTableInfo.getDiscriminatorPropertyConfig().getColumnName();

      Integer discriminatorColumnIndex = columnPositions.get(discriminatorColumnName);
      if (discriminatorColumnIndex == null) {
        discriminatorColumnIndex = results.findColumn(discriminatorColumnName);
        if (discriminatorColumnIndex >= 0)
          columnPositions.put(discriminatorColumnName, discriminatorColumnIndex);
        else {
          discriminatorColumnIndex = null;
          // TODO: is this correct?
          return entityConfig.createObject();
        }
      }

      String discriminatorValue =
          results.getString(discriminatorColumnIndex); // TODO: check for Discriminator type first
      EntityConfig resultEntityEntityConfig =
          joinedTableInfo.getEntityForDiscriminatorValue(discriminatorValue);

      instancePropertyConfigs.addAll(joinedTableInfo.getSubClassFieldTypes(discriminatorValue));

      return (T) resultEntityEntityConfig.createObject();
    }
  }
예제 #2
0
 public T moveRelative(int offset) throws SQLException {
   if (closed) {
     return null;
   }
   first = false;
   if (results.moveRelative(offset)) {
     return getCurrent();
   } else {
     return null;
   }
 }
예제 #3
0
 public T previous() throws SQLException {
   if (closed) {
     return null;
   }
   first = false;
   if (results.previous()) {
     return getCurrent();
   } else {
     return null;
   }
 }
예제 #4
0
 /**
  * Returns whether or not there are any remaining objects in the table. Can be called before
  * next().
  *
  * @throws SQLException If there was a problem getting more results via SQL.
  */
 public boolean hasNextThrow() throws SQLException {
   if (closed) {
     return false;
   }
   if (alreadyMoved) {
     // we do this so multiple hasNext() calls can be made, result would be true or closed is true
     return true;
   }
   boolean result;
   if (first) {
     first = false;
     result = results.first();
   } else {
     result = results.next();
   }
   if (!result) {
     close();
   }
   alreadyMoved = true;
   return result;
 }
예제 #5
0
 public T nextThrow() throws SQLException {
   if (closed) {
     return null;
   }
   if (!alreadyMoved) {
     boolean hasResult;
     if (first) {
       first = false;
       hasResult = results.first();
     } else {
       hasResult = results.next();
     }
     // move forward
     if (!hasResult) {
       first = false;
       return null;
     }
   }
   first = false;
   return getCurrent();
 }
예제 #6
0
 @Override
 public Object resultToSqlArg(FieldType fieldType, DatabaseResults results, int columnPos)
     throws SQLException {
   return (Long) results.getLong(columnPos);
 }
예제 #7
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;
  }