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(); } }
public T moveRelative(int offset) throws SQLException { if (closed) { return null; } first = false; if (results.moveRelative(offset)) { return getCurrent(); } else { return null; } }
public T previous() throws SQLException { if (closed) { return null; } first = false; if (results.previous()) { return getCurrent(); } else { return null; } }
/** * 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; }
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(); }
@Override public Object resultToSqlArg(FieldType fieldType, DatabaseResults results, int columnPos) throws SQLException { return (Long) results.getLong(columnPos); }
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; }