It seems that the ORM attempts to hydrate a column marked as timestamp
, even if it has a value transformer applied to it. What results is that, in DateUtils.ts L24, the value that TypeORM expects to be a date is already the transformed value (e.g.: in the example below, it is a LocalDateTime
, rather than the expected Date
).
This is replicable using the latest published TypeORM version. In the example below, setting varchar
as the column type works around the issue.
Example:
Note: LocalDateTime
is a js-joda type (not sure if relevant).
ModelExample.ts
@Entity('modelexample')
export class ModelExample {
@PrimaryColumn('uuid')
id: string
@Column('timestamp', { name: 'date_time', transformer: new LocalDateTimeValueTransformer() })
dateTime: LocalDateTime
}
LocalDateTimeValueTransformer.ts
export class LocalDateTimeValueTransformer implements ValueTransformer {
to (value: LocalDateTime): string {
return value.toString()
}
from (value: string): LocalDateTime {
return LocalDateTime.parse(value)
}
}
index.ts
[Some database initialization code...]
const repository = database.getRepository(ModelExample)
const model = new ModelExample()
model.id = 'cbbb2918-b9ab-4463-997e-b2cc47c62a21'
model.dateTime = LocalDateTime.now()
await repository.save(model)
// Throws "TypeError: date.getFullYear is not a function"
const savedModel = repository.findOneById('cbbb2918-b9ab-4463-997e-b2cc47c62a21')
Full stack trace:
TypeError: date.getFullYear is not a function
at Function.Object.<anonymous>.DateUtils.normalizeHydratedDate (src/util/DateUtils.ts:24:43)
at PostgresDriver.Object.<anonymous>.PostgresDriver.prepareHydratedValue (src/driver/postgres/PostgresDriver.ts:324:30)
at src/query-builder/transformer/RawSqlResultsToEntityTransformer.ts:107:55
at Array.forEach (native)
at RawSqlResultsToEntityTransformer.Object.<anonymous>.RawSqlResultsToEntityTransformer.transformColumns (src/query-builder/transformer/RawSqlResultsToEntityTransformer.ts:97:26)
at RawSqlResultsToEntityTransformer.Object.<anonymous>.RawSqlResultsToEntityTransformer.transformRawResultsGroup (src/query-builder/transformer/RawSqlResultsToEntityTransformer.ts:83:27)
at src/query-builder/transformer/RawSqlResultsToEntityTransformer.ts:38:32
at Array.map (native)
at RawSqlResultsToEntityTransformer.Object.<anonymous>.RawSqlResultsToEntityTransformer.transform (src/query-builder/transformer/RawSqlResultsToEntityTransformer.ts:38:14)
at SelectQueryBuilder.<anonymous> (src/query-builder/SelectQueryBuilder.ts:1689:36)
at step (node_modules/typeorm/query-builder/SelectQueryBuilder.js:42:23)
at Object.next (node_modules/typeorm/query-builder/SelectQueryBuilder.js:23:53)
at fulfilled (node_modules/typeorm/query-builder/SelectQueryBuilder.js:14:58)
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
I've run in to this issue too.
It'd be nice if the transform bypassed all the other mutations _or_ there was some column metadata that you could use to get that behaviour when requested.
I'm happy to write a patch for this, does anyone have a preference on the behaviour (currently I'm thinking of just altering the driver to not alter data if there was a transform applied).
I've created #1524 which ignores further manipulation if a transform is supplied.
I've closed #1524 and replaced it with #1547 which I think addresses @pleerock 's concerns with the original PR.
Most helpful comment
I've created #1524 which ignores further manipulation if a transform is supplied.