I am having issues updating my Chat entity with new messages. I have tried different methods and am currently getting Error: Cannot query across one-to-many for property messages
chat.entity.ts
import {
Entity,
PrimaryGeneratedColumn,
Column,
ManyToOne,
JoinColumn,
OneToMany,
OneToOne,
} from 'typeorm';
import { ApiProperty } from '@nestjs/swagger';
import { ChatMessage } from '../chatMessage/chatMessage.entity';
import { User } from 'src/auth/user.entity';
import { Session } from 'src/sessions/session.entity';
@Entity()
export class Chat {
@PrimaryGeneratedColumn()
id: number;
@ManyToOne(() => User, (user) => user.chats)
@ApiProperty({
type: () => User,
})
user: User;
@ApiProperty({
example: '2024-02-09T22:15:11.293Z',
description: 'session_id',
})
@Column()
session_id: string;
@ApiProperty({
type: () => Session,
example: '',
description: '',
})
@OneToOne(() => Session)
@JoinColumn()
session: Session;
@ApiProperty({
type: () => ChatMessage,
example: '',
description: 'chat message',
})
@OneToMany(() => ChatMessage, (chatMessage) => chatMessage.chat)
@Column('jsonb', { default: [] })
@JoinColumn()
messages: ChatMessage[];
}
chatMessage.entity.ts
import {
Entity,
Column,
PrimaryGeneratedColumn,
OneToMany,
JoinColumn,
} from 'typeorm';
import { ApiProperty } from '@nestjs/swagger';
import { Chat } from '../chat/chat.entity';
export class DataDto {
// Not sure why type is in both objects but that's how langchain structures it.
@ApiProperty({ example: 'human', description: 'type' })
@Column()
type: string;
@ApiProperty({
example:
'Mr. Smith is an investment banker at a large bank and primarily works with water risk data. What product or products should we recommend?',
description: 'content',
})
@Column()
content: string;
@Column('jsonb', { nullable: true })
additional_kwargs: any; // TODO: Figure out how to define this type
@ApiProperty({ example: false, description: 'Bool for example' })
@Column()
example: boolean;
}
@Entity()
export class ChatMessage {
@PrimaryGeneratedColumn()
id: number;
@ApiProperty({
type: () => Chat,
example: '',
description: '',
})
@OneToMany(() => Chat, (chat: Chat) => chat.messages)
@JoinColumn()
chat: Chat;
@ApiProperty({
example: 'human',
description: 'type',
nullable: true,
enum: ['human', 'bot'],
})
@Column({ nullable: true, enum: ['human', 'bot'] })
type: string;
@Column('jsonb', { nullable: true })
data: DataDto;
}
chat.service.ts
@Injectable()
export class ChatService {
constructor(
@InjectRepository(Chat)
private chatRepository: Repository<Chat>,
) {}
async patch(id: number, Chat: Partial<Chat>): Promise<any> {
const chat = await this.chatRepository.findOne({ where: { id } });
if (!chat) {
throw new Error('Chat not found');
}
console.debug('ChatService.patch chat:', chat);
console.debug('ChatService.patch Chat:', Chat);
const concatenatedMessages = chat.messages.concat(Chat.messages);
console.debug(
'ChatService.patch concatenatedMessages:',
concatenatedMessages,
);
return await this.chatRepository.update(id, {
messages: concatenatedMessages,
});
figured it out:
chatMessage.entity.ts: replace@OneToManyin ChatMessage.chat with@ManyToOnechat.entity.ts: remove@JoinColumn()in Chat.messageschat.service.ts: update withconst chat = await this.chatRepository.findOne({ where: { id }, relations: { messages: true }, });