-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Description
Issue Description
When an entity with a STORED generated column is saved, the generated column is not included in the RETURNING clause, causing the object not to get populated with the generated column's value.
Expected Behavior
query: START TRANSACTION
query: INSERT INTO "typeorm"."user"("generated", "email", "username", "password") VALUES (DEFAULT, $1, $2, $3) RETURNING "counter", "generated" -- PARAMETERS: ["[email protected]","username","hash"]
query: COMMITThe generated generated column is in the RETURNING statement.
BEFORE SAVE: UserEntity {
email: '[email protected]',
username: 'username',
password: 'hash'
}
AFTER SAVE: UserEntity {
counter: 2,
generated: 4,
email: '[email protected]',
username: 'username',
password: 'hash'
}
WHEN FETCHING MANUALLY: UserEntity {
counter: 2,
generated: 4,
email: '[email protected]',
username: 'username',
password: 'hash'
}Actual Behavior
Using the new stored generated column type:
query: START TRANSACTION
query: INSERT INTO "typeorm"."user"("generated", "email", "username", "password") VALUES (DEFAULT, $1, $2, $3) RETURNING "counter" -- PARAMETERS: ["[email protected]","username","hash"]
query: COMMITAs you can see, the column generated is not in the RETURNING statement, which causes the entity not to get populated properly with the column's value:
BEFORE SAVE: UserEntity {
email: '[email protected]',
username: 'username',
password: 'hash'
}
AFTER SAVE: UserEntity {
counter: 2,
email: '[email protected]',
username: 'username',
password: 'hash'
}
WHEN FETCHING MANUALLY: UserEntity {
counter: 2,
generated: 4,
email: '[email protected]',
username: 'username',
password: 'hash'
}Steps to Reproduce
@Entity()
export class UserEntity extends BaseEntity {
@PrimaryGeneratedColumn()
counter: number;
// generated column defined here
@Column({
type: "int",
generatedType: "STORED",
asExpression: `counter * 2`,
})
generated: number;
@Column({unique: true, nullable: true})
email?: string;
@Column({length: 32})
username: string;
@Column({nullable: true})
password?: string;
}The code I use to test this:
const user = UserEntity.create({email, password, username});
console.log("BEFORE SAVE:", user)
user.save();
console.log("AFTER SAVE:", user)
const userFound = await UserEntity.find({where: {email}})
console.log("WHEN FETCHING MANUALLY:", userFound)My Environment
| Dependency | Version |
|---|---|
| Operating System | Windows 11 |
| Node.js version | v16.13.1 |
| Typescript version | 4.4.4 |
| TypeORM version | 0.2.41 |
Additional Context
The generated column feature was implemented in the PostgreSQL driver by #6469, so perhaps @TheNoim knows what's missing.
The column seems to be missing from this array:
typeorm/src/query-builder/ReturningResultsEntityUpdator.ts
Lines 172 to 187 in 90a8deb
| getInsertionReturningColumns(): ColumnMetadata[] { | |
| // for databases which support returning statement we need to return extra columns like id | |
| // for other databases we don't need to return id column since its returned by a driver already | |
| const needToCheckGenerated = this.queryRunner.connection.driver.isReturningSqlSupported(); | |
| // filter out the columns of which we need database inserted values to update our entity | |
| return this.expressionMap.mainAlias!.metadata.columns.filter(column => { | |
| return column.default !== undefined || | |
| (needToCheckGenerated && column.isGenerated) || | |
| column.isCreateDate || | |
| column.isUpdateDate || | |
| column.isDeleteDate || | |
| column.isVersion; | |
| }); | |
| } |
column.isGenerated is false, to be specific.
Relevant Database Driver(s)
| DB Type | Reproducible |
|---|---|
aurora-data-api |
no |
aurora-data-api-pg |
no |
better-sqlite3 |
no |
cockroachdb |
no |
cordova |
no |
expo |
no |
mongodb |
no |
mysql |
yes |
nativescript |
no |
oracle |
no |
postgres |
yes |
react-native |
no |
sap |
no |
sqlite |
no |
sqlite-abstract |
no |
sqljs |
no |
sqlserver |
no |
Are you willing to resolve this issue by submitting a Pull Request?
- ✅ Yes, I have the time, and I know how to start.
- ✖️Yes, I have the time, but I don't know how to start. I would need guidance.
- ✖️ No, I don’t have the time, but I can support (using donations) development.
- ✖️ No, I don’t have the time and I’m okay to wait for the community / maintainers to resolve this issue.