typeorm: Cannot update entity with relation

Issue type:

[ ] question [x] bug report [ ] feature request [ ] documentation issue

Database system/driver:

[ ] cordova [ ] mongodb [ ] mssql [ ] mysql / mariadb [ ] oracle [x] postgres [ ] cockroachdb [ ] sqlite [ ] sqljs [ ] react-native [ ] expo

TypeORM version:

[x ] latest [ ] @next [ ] 0.x.x (or put your version here)

Example

Given these entities:

@Entity('users')
export default class UserEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;
    
  @Column()
  name: string

  @OneToMany(type => Photo, photo => photo.user, { eager: true })
  photos: Photo[];
}


@Entity('photos')
export class Photo {

  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  url: string;

  @ManyToOne(type => User, user => user.photos)
  user: User;
}

Given these update and create functions:


export async function createUser(user): Promise<UserEntity> {
  const userRepo: Repository<UserEntity> = getRepository(UserEntity);

  const newUser = userRepo.create(user);
  return userRepo.save(newUser)
}

export async function updateUser(existingUser: UserEntity) {
  const userRepo: Repository<UserEntity> = getRepository(UserEntity);
	
  return userRepo.update({ id: existingUser.id }, existingUser)
}

Updating fails:

const user =  await createUser({ name: 'foo'})
user.name = 'bar'
await updateUser(user)

With this error: EntityColumnNotFound: No entity column "photos" was found.

Stacktrace:

EntityColumnNotFound: No entity column "photos" was found.
    at new EntityColumnNotFound (/home/olingern/work/server/node_modules/typeorm/error/EntityColumnNotFound.js:10:28)
    at /home/olingern/work/server/node_modules/typeorm/query-builder/UpdateQueryBuilder.js:318:27
    at Array.forEach (<anonymous>)
    at UpdateQueryBuilder.createUpdateExpression (/home/olingern/work/server/node_modules/typeorm/query-builder/UpdateQueryBuilder.js:314:85)
    at UpdateQueryBuilder.getQuery (/home/olingern/work/server/node_modules/typeorm/query-builder/UpdateQueryBuilder.js:40:24)
    at UpdateQueryBuilder.QueryBuilder.getQueryAndParameters (/home/olingern/work/server/node_modules/typeorm/query-builder/QueryBuilder.js:224:26)
    at UpdateQueryBuilder.<anonymous> (/home/olingern/work/server/node_modules/typeorm/query-builder/UpdateQueryBuilder.js:81:50)
    at step (/home/olingern/work/server/node_modules/tslib/tslib.js:136:27)
    at Object.next (/home/olingern/work/server/node_modules/tslib/tslib.js:117:57)
    at /home/olingern/work/server/node_modules/tslib/tslib.js:110:75
    at new Promise (<anonymous>)
    at Object.__awaiter (/home/olingern/work/server/node_modules/tslib/tslib.js:106:16)
    at UpdateQueryBuilder.execute (/home/olingern/work/server/node_modules/typeorm/query-builder/UpdateQueryBuilder.js:49:24)
    at EntityManager.update (/home/olingern/work/server/node_modules/typeorm/entity-manager/EntityManager.js:300:18)
    at Repository.update (/home/olingern/work/server/node_modules/typeorm/repository/Repository.js:102:29)
    at Object.updateUser (/home/olingern/work/server/dist/app/services/UserService.js:55:21)
    at getOrganisationSettings (/home/olingern/work/server/dist/app/controllers/UserController.js:253:27)
    at processTicksAndRejections (internal/process/task_queues.js:89:5) {
  name: 'EntityColumnNotFound',
  message: 'No entity column "photos" was found.'
}

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 31
  • Comments: 20

Commits related to this issue

Most upvoted comments

Euh yes. This is my code

async update(newuser: User) {
       // newUser and My old user have the same matricule
       const getUserFromDB = await this.userRepository.findOne({matricule: newuser.matricule });
       this.userRepository.merge(getUserFromDB, newuser);
       this.userRepository.save(getUserFromDB)
          .then(
                      (data) => {
                          console.log('success');
                      },
                      (err) => {
                          // error
                          console.log(err);
                      },
                  );
    }

After adding

@ManyToOne(type => User, user=> user.photo, 
{onUpdate: 'CASCADE', onDelete: 'CASCADE'}
)

I have no more the error : EntityColumnNotFound: No entity column “photos” was found. Hope it helps

So how are you actually supposed update a relation without fetching the whole entity with find, merge and save? This isn’t atomic in any way. I don’t want to update the whole entity data, I just want to add a row to the id-to-id table that describes the relation…

To those stumbling on this issue: I think it has to do with how to use TypeORM.

I have a Task entity, and each Task can have many Timeboxes. So I had the same problem as mentioned here when I was attempting to update a Task:

EntityColumnNotFound: No entity column "timeboxes" was found.

The problem was that my frontend was sending the Task’s data to the backend with timeboxes, the array of Timeboxes. My payload was like this (simplified a bit):

{
  "id": 31,
  "title": "Fix that nasty bug",
  "timeboxes": [{ "id": 132 }, { "id": 187 }]
}

when it should have been only the Task entity’s intrinsic fields:

{
  "id": 31,
  "title": "Fix that nasty bug"
}

You should set { cascade: true} on the parent relation (the one through you want to make the update) and { onDelete: true, onUpdate: true } on the child relation.

Also, note the differences between the .save() and .update() when working with relationships.

/**
 * Updates entity partially. Entity can be found by a given conditions.
 * Unlike save method executes a primitive operation without cascades, relations and other operations included.
 * Executes fast and efficient UPDATE query.
 * Does not check if entity exist in the database.
 */
update(criteria: string | string[] | number | number[] | Date | Date[] | ObjectID | ObjectID[] | FindConditions<Entity>, partialEntity: QueryDeepPartialEntity<Entity>): Promise<UpdateResult>;

Therefore, I recommend using .save() instead of .update().

I have the same problem, but I can’t use the save method since I have a unique column and it throws me an error if I don’t update that column, any solution to this?

spent some time in this… couldn’t get this to work using update. @TidianeRolland thank you, merge & save did the trick.

Yea this is pretty annoying. Happening to me too.

It seems this is the source of the error: https://github.com/typeorm/typeorm/blob/7d7fd9f00ca45013d86ba8d570b66bd15b62d69d/src/query-builder/UpdateQueryBuilder.ts#L373

It’s expected that photos is a column, but it is not.

If I comment the throw out, it executes fine. Logging the metadata I see:

ownRelations: [
  RelationMetadata {
    isTreeParent: false,
    isTreeChildren: false,
    isPrimary: false,
    isLazy: false,
    isEager: true,
    persistenceEnabled: true,
    isCascadeInsert: true,
    isCascadeUpdate: true,
    isCascadeRemove: true,
    isNullable: true,
    isOwning: false,
    isOneToOne: false,
    isOneToOneOwner: false,
    isWithJoinColumn: false,
    isOneToOneNotOwner: false,
    isOneToMany: true,
    isManyToOne: false,
    isManyToMany: false,
    isManyToManyOwner: false,
    isManyToManyNotOwner: false,
    foreignKeys: [],
    joinColumns: [],
    inverseJoinColumns: [],
    entityMetadata: [Circular],
    embeddedMetadata: undefined,
    target: [Function: UserEntity],
    propertyName: 'photos',
    relationType: 'one-to-many',
    givenInverseSidePropertyFactory: [Function],
    onDelete: undefined,
    onUpdate: undefined,
    deferrable: undefined,
    type: [Function: OrganizationEntity],
    propertyPath: 'photos',
    inverseEntityMetadata: [EntityMetadata],
    inverseSidePropertyPath: 'user',
    inverseRelation: [RelationMetadata]
  }
],

Just a question. Why is it necessary to throw when a relation column can’t be found? Those entities need to be updated and saved on their own, no? I would prefer a warning over an error if the query can still execute

I’m relatively new to typeorm, so I could just be doing something wrong since this seems like a basic use case.