Skip to content

EntitySchema missing support for multiple joinColumns in relations #5444

@pwbrown

Description

@pwbrown

Issue type:

[x] bug report

TypeORM version:

[x] 0.2.22

Inconsistent Feature:

When defining a JoinColumn using decorators, it accepts an array of JoinColumnOptions:

@Entity()
class Example {
    .
    .
    .
    @ManyToOne(type => Entity, entity => entity.col)
    @JoinColumn([
        { name: 'col1', referencedColumnName: 'col1' },
        { name: 'col2', referencedColumnName: 'col2' },
    ])
    relationship!: Entity;
}

However when defining a relation using an EntitySchema, the joinColumn option only accepts a single column object

interface Example {
    col1: string;
    relationship?: Entity;
}

const ExampleEntity = new EntitySchema<Example>({
    name: 'Example',
    columns: { ... },
    relation: {
        relationship: {
            type: 'many-to-one',
            target: 'Entity',
            inverseSide: 'col',
            /** ALLOWED */
            joinColumn: {
                name: 'col1',
                referencedColumnName: 'col2',
            },
            /** NOT ALLOWED */
            joinColumn: [
                { name: 'col1', referencedColumnName: 'col1'  },
                { name: 'col2', referencedColumnName: 'col2' },
            ],
        },
    },
})

Code References:

  1. src/decorator/relations/JoinColumn.ts - Correct functionality reference (iterates over join columns and adds metadata for each)

lines 30-42

export function JoinColumn(optionsOrOptionsArray?: JoinColumnOptions|JoinColumnOptions[]): Function {
    return function (object: Object, propertyName: string) {
        const options = optionsOrOptionsArray instanceof Array ? optionsOrOptionsArray : [optionsOrOptionsArray || {}];
        options.forEach(options => {
            getMetadataArgsStorage().joinColumns.push({
                target: object.constructor,
                propertyName: propertyName,
                name: options.name,
                referencedColumnName: options.referencedColumnName
            } as JoinColumnMetadataArgs);
        });
    };
}
  1. src/entity-schema/EntitySchemaRelationOptions.ts - definition should allow for an array of JoinColumnOptions

line 58 - incorrect

joinColumn?: boolean|JoinColumnOptions;

line 58 - corrected

joinColumn?: boolean|JoinColumnOptions|JoinColumnOptions[];
  1. src/entity-schema/EntitySchemaTransformer.ts - transformer should add multiple joinColumns when an array is passed

line 152-158 - incorrect

const joinColumn: JoinColumnMetadataArgs = {
    target: options.target || options.name,
    propertyName: relationName,
    name: relationSchema.joinColumn.name,
    referencedColumnName: relationSchema.joinColumn.referencedColumnName
};
metadataArgsStorage.joinColumns.push(joinColumn);

line 152-161 - corrected

const joinColumns = relationSchema.joinColumn instanceof Array ? relationSchema.joinColumn : [relationSchema.joinColumn || {}];
joinColumns.forEach(joinColumnOptions => {
    const joinColumn: JoinColumnMetadataArgs = {
        target: options.target || options.name,
        propertyName: relationName,
        name: joinColumnOptions.name,
        referencedColumnName: joinColumnOptions.referencedColumnName
    };
    metadataArgsStorage.joinColumns.push(joinColumn);
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions