crud: 'WHERE' of the join query is generated "wrong"
Hello guys, I did a test using ManyToOne but I get the following error:
error: error: invalid reference to FROM-clause entry for table "comment"
The error occurs when I run the following route
GET http://localhost:3000/post/1/comment
Looking at the log, I saw the following QUERY:
SELECT "Comment"."id" AS "Comment_id", "Comment"."text" AS "Comment_text", "post"."id" AS "post_id", "post"."body" AS "post_body", "post"."commentsId" FROM "comment" "Comment" LEFT JOIN "post" "post" ON "post"."commentsId"="Comment"."id" WHERE (Comment.postId = $1)
And doing tests directly in the database and works with this SQL (I added the quotes on WHERE it)
SELECT "Comment"."id" AS "Comment_id", "Comment"."text" AS "Comment_text", "post"."id" AS "post_id", "post"."body" AS "post_body", "post"."commentsId" FROM "comment" "Comment" LEFT JOIN "post" "post" ON "post"."commentsId"="Comment"."id" WHERE ("Comment"."postId" = $1)
It is probably some wrong setting I made. I did some tests and research, both in TypeORM, and directly in the PG plugin but I was not successful.
follows some useful files
dependencies in package.json
"dependencies": {
"@nestjs/common": "^6.7.2",
"@nestjs/core": "^6.7.2",
"@nestjs/platform-express": "^6.7.2",
"@nestjs/typeorm": "^6.2.0",
"@nestjsx/crud": "^4.4.1",
"@nestjsx/crud-typeorm": "^4.4.1",
"class-transformer": "^0.2.3",
"class-validator": "^0.11.0",
"pg": "^7.17.1",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.0",
"rxjs": "^6.5.3",
"typeorm": "^0.2.22"
},
Main Module
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PostModule } from './post/post.module';
import { CommentModule } from './comment/comment.module';
import { Comment } from './comment/comment.entity';
import { Post } from './post/post.entity';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'postgres',
database: 'test',
logging: true,
entities: [
Post, Comment
],
synchronize: true,
}),
PostModule,
CommentModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Entities
Post
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm";
import { Comment } from '../comment/comment.entity';
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number
@Column()
body: string
@ManyToOne(type => Comment, c => c.post)
comments: Post[]
}
Comment
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
import { Post } from '../post/post.entity';
@Entity()
export class Comment {
@PrimaryGeneratedColumn()
id: number
@Column()
text: string
@OneToMany(type => Post, p => p.comments)
post: Post
}
Modules
Post
import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { Comment } from "./comment.entity";
import { CommentService } from "./comment.service";
import { CommentController } from "./comment.controller";
@Module({
imports: [TypeOrmModule.forFeature([Comment])],
providers: [CommentService],
exports: [CommentService],
controllers: [CommentController]
})
export class CommentModule {}
Comment
import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { Post } from "./post.entity";
import { PostService } from "./post.service";
import { PostController } from "./post.controller";
@Module({
imports: [TypeOrmModule.forFeature([Post])],
providers: [PostService],
exports: [PostService],
controllers: [PostController]
})
export class PostModule {}
Services
Post
import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { TypeOrmCrudService } from "@nestjsx/crud-typeorm";
import { Comment } from "./comment.entity";
@Injectable()
export class CommentService extends TypeOrmCrudService<Comment> {
constructor(@InjectRepository(Comment) repo) {
super(repo);
}
}
Comment
import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { TypeOrmCrudService } from "@nestjsx/crud-typeorm";
import { Comment } from "./comment.entity";
@Injectable()
export class CommentService extends TypeOrmCrudService<Comment> {
constructor(@InjectRepository(Comment) repo) {
super(repo);
}
}
Controller
Post
import { Controller } from "@nestjs/common";
import { Crud, CrudController } from "@nestjsx/crud";
import { Comment } from "./comment.entity";
import { CommentService } from "./comment.service";
@Crud({
model: {
type: Comment
},
params: {
id: {
field: 'id',
type: 'number',
primary: true,
},
postId: {
field: 'postId',
type: 'number'
},
},
query: {
join: {
post: {
eager: true
}
}
}
})
@Controller("post/:postId/comment")
export class CommentController implements CrudController<Comment> {
constructor(public service: CommentService) {}
}
Comment
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
What am I doing wrong? I already appreciate the help š
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 3
- Comments: 30 (10 by maintainers)
hey sorry to comment in a closed ticket, i just updated nextjs crud and iām having same issue in postgresql when filtering results in CrudAuth by a related column for example :
generates this error
But if i use
works!
thanks
Iāll publish it today. Sorry for the delay
fixed in v4.6.0
@zMotivat0r, guys, I think this fix may have leaked over into mysql and into other things. I had a working simple filter that I havenāt touched in a week or two:
Itās hitting a pretty simple entity on the other end. I even commented out all the joins so itās just a couple of primitive columns.
and all of a sudden Iām getting the following error:
and this is what typeorm is spitting out
notice the
WHERE ("GameTheme"."is_public" = ?)- itās in double quotes which is illegal in mysql. When I paste it into workbench and change the double quotes to backticks, it runs fine. I have a feeling this issue is the cause.Update ā the following function seems to be missing the quoting:
This line: https://github.com/nestjsx/crud/blob/76dc6c2bc841a9b6fdc68b730aa87043f327117b/packages/crud-typeorm/src/typeorm-crud.service.ts#L782
Not 100% sure the fix is on that line, or if itās intended to delegate to the underlying library but adding the quotes here fixes it for me for postgres. I can try to put up a PR this weekend. Tagging: @zMotivat0r if you have a chance to peek at this.
Reminded by @mkelandis , I think I found the root cause. I read the code in
packages/crud-typeorm/src/typeorm-crud.service.tsand find this function:in the first line we can see that the value of
iis base ondbName, only check if the value ofdbNameismysqlor not, but in my project I setmariadbto theTypeOrmModuleOptions.type(ormconfig.json). I think bothmysqlandmariadbshould be supported. Now I just change it tomysqlthen it works.fixed in v4.6.1