Upgrading from v2 to v3
Following sections describe (hopefully) all breaking changes, most of them might be not valid for you, like if you do not use custom NamingStrategy
implementation, you do not care about the interface being changed.
Default value of autoFlush has changed to false
If you had
autoFlush: false
in your ORM configuration before, you can now remove this line, no changes are needed in your app.
Default value for autoFlush
is now false
. That means you need to call em.flush()
yourself to persist changes into database. You can still change this via ORM's options to ease the transition, but generally it is not recommended as it can cause unwanted small transactions being created around each persist
.
orm.em.persist(new Entity()); // no auto-flushing by default
await orm.em.flush();
await orm.em.persist(new Entity(), true); // you can still use second parameter to auto-flush
Reworked entity definition
Implementing those interfaces is optional.
Now it is no longer needed to merge entities with IEntity
interface, that was polluting entity's interface with internal methods. New interfaces IdentifiedEntity<T>
, UuidEntity<T>
and MongoEntity<T>
are introduced, that can be implemented by entities. They are not adding any new properties or methods, keeping the entity's interface clean. This is also the reason why they can be omitted.
IEntity
interface has been renamed to AnyEntity<T, PK>
and it no longer has public methods like toJSON()
, toObject()
or init()
. One can use wrap()
method provided by ORM that will enhance property type when needed with those methods (await wrap(book.author).init()
). To keep all methods available on the entity, you can still use interface merging with WrappedEntity<T, PK>
that both extends AnyEntity<T, PK>
and defines all those methods.
You can mark the entity by implementing one of *Entity
interfaces:
IdEntity<T>
for numeric/string PK onid
property (id: number
)UuidEntity<T>
for string PK onuuid
property (uuid: string
)MongoEntity<T>
for mongo, whereid: string
and_id: ObjectId
are requiredAnyEntity<T, PK>
for other possible properties (fill the PK property name toPK
parameter, e.g.:AnyEntity<Book, 'myPrimaryProperty'>'
)
To keep all public methods that were part of IEntity
interface in v2, you can use WrappedEntity<T, PK>
via interface merging:
@Entity()
export class Book { ... }
export interface Book extends WrappedEntity<Book, 'id'> { }
For more examples, take a look at defining entities section.
Integrated Knex.js as query builder and runner
QueryBuilder
now internally uses knex to run all queries. As knex already supports connection pooling, this feature comes without any effort. New configuration for pooling is now available
Transactions now require using em.transactional()
method, previous helpers beginTransaction
/commit
/rollback
are now removed.
All transaction management has been removed from IDatabaseDriver
interface, now EM handles this, passing the transaction context (carried by EM, and created by Connection
) to all driver methods. New methods on EM exists: isInTransaction()
and getTransactionContext()
.
In postgres driver, it used to be required to pass parameters as indexed dollar sign ($1, $2, ...), while now knex requires the placeholder to be simple question mark (?
), like in other dialects, so this is now unified with other drivers.
ManyToMany now uses composite primary key
Previously it was required to have autoincrement primary key for m:n pivot tables. Now this has changed. By default, only foreign columns are required and composite key over both of them is used as primary key.
To preserve stable order of collections, you can force previous behaviour by defining the m:n property as fixedOrder: true
, which will start ordering by id
column. You can also override the order column name via fixedOrderColumn: 'order'
.
You can also specify default ordering via orderBy: { ... }
attribute.
Entity references now don't have instantiated collections
Previously all entity instances, including entity references (not fully loaded entities where we know only the primary key), had instantiated collection classes. Now only initialized entities have them.
const book = em.getReference(Book, 1);
console.log(book.tags); // undefined
await book.init();
console.log(book.tags); // instance of Collection (not initialized)
EntityAssigner.assign() requires EM for new entities
Previously all entities had internal reference to the root EM - the one created when initializing the ORM. Now only managed entities (those merged to the EM, e.g. loaded from the database) have this internal reference.
To use assign()
method on new (not managed) entities, you need to provide the em
parameter:
const book = new Book();
wrap(book).assign(data, { em: orm.em });
Strict FilterQuery and smart query conditions
FilterQuery
now does not allow using smart query operators. You can either cast your condition as any or use object syntax instead (instead of { 'age:gte': 18 }
use { age: { $gte: 18 } }
).
Logging configuration
Previously to start logging it was required to provide your custom logger. Logger now defaults to console.log()
, and users can specify what namespaces are they interested in via debug
option. true
/false
will enable/disable all namespaces.
Available logger namespaces: 'query' | 'query-params' | 'discovery' | 'info'
.
Removed deprecated fk option from 1:m and m:1 decorators
Use mappedBy
/inversedBy
instead.
SchemaGenerator.generate() is now async
If you used SchemaGenerator
, now there is CLI tool you can use instead. Learn more in SchemaGenerator docs. To set up CLI, take a look at installation section.
New method on NamingStrategy interface
getClassName()
is used to find entity class name based on its file name. Now users can override the default implementation to accommodate their specific needs.
If you used custom naming strategy, you will either need to implement this method yourself, or extend AbstractNamingStrategy
.
TypescriptMetadataProvider has been renamed
The name is now TsMorphMetadataProvider
, there is also newly added ReflectMetadataProvider
that uses reflect-metadata
instead. As TypescriptMetadataProvider
was the default, no changes should be required.
Updated mongodb driver
MongoDB driver version 3.3.4 or higher is now required.
EntityManager.find() now requires where parameter
EntityManager
has now same find
method interface aligned with EntityRepository
, where
parameter is now required. To select all entities, use em.find(Entity, {})
as value.