Repository: typeorm/typeorm
File: src/query-builder/transformer/RawSqlResultsToEntityTransformer.ts (TypeScript)

Code before:
        entity: ObjectLiteral,
        metadata: EntityMetadata,
    ): boolean {
        let hasData = false
        metadata.columns.forEach((column) => {
            // if table inheritance is used make sure this column is not child's column
            if (
                metadata.childEntityMetadatas.length > 0 &&
                metadata.childEntityMetadatas.findIndex(
                    (childMetadata) => childMetadata.target === column.target,
                ) !== -1
            )
                return

            const value =
                rawResults[0][
                    DriverUtils.buildAlias(
                        this.driver,
                        undefined,
                        alias.name,
                        column.databaseName,
                    )
                ]
            if (value === undefined || column.isVirtual) return

            // if user does not selected the whole entity or he used partial selection and does not select this particular column
            // then we don't add this column and its value into the entity
            if (
                !this.expressionMap.selects.find(
                    (select) =>
                        select.selection === alias.name ||
                        select.selection ===
                            alias.name + "." + column.propertyPath,
                )
            )
                return

            column.setEntityValue(
                entity,
                this.driver.prepareHydratedValue(value, column),
            )
            if (value !== null)
                // we don't mark it as has data because if we will have all nulls in our object - we don't need such object
                hasData = true
        })
        return hasData
    }

    /**
     * Transforms joined entities in the given raw results by a given alias and stores to the given (parent) entity
     */

Review comment (suggestion):
Maybe we should rename `key` as `columnAlias`?
It would make the code a bit more explicit since the method name `getColumnsToProcess()` is not indicating what `key` is.


Code after:

        // if we don't have any selected column we should not return entity,
        // except for the case when entity only contain a primary column as a relation to another entity
        // in this case its absolutely possible our entity to not have any columns except a single relation
        const hasOnlyVirtualPrimaryColumns = metadata.primaryColumns.every(
            (column) => column.isVirtual === true,
        ) // todo: create metadata.hasOnlyVirtualPrimaryColumns
        if (
            hasOnlyVirtualPrimaryColumns &&
            (hasRelations || hasRelationIds || hasRelationCounts)
        )
            return entity

        return undefined
    }

    // get value from columns selections and put them into object
    protected transformColumns(
        rawResults: any[],
        alias: Alias,
        entity: ObjectLiteral,
        metadata: EntityMetadata,
    ): boolean {
        let hasData = false
        const result = rawResults[0]
        for (const [key, column] of this.getColumnsToProcess(
            alias.name,
            metadata,
        )) {
            const value = result[key]

            if (value === undefined) continue
            // we don't mark it as has data because if we will have all nulls in our object - we don't need such object
            else if (value !== null) hasData = true

            column.setEntityValue(
                entity,
                this.driver.prepareHydratedValue(value, column),
            )
        }
        return hasData
    }

    /**
     * Transforms joined entities in the given raw results by a given alias and stores to the given (parent) entity
     */
    protected transformJoins(
        rawResults: any[],
        entity: ObjectLiteral,
        alias: Alias,
        metadata: EntityMetadata,