在PostgreSQL中用Jakarta Persistence能否不新建实体为关联表加属性?
问题
我通过以下代码实现了多对多关系:
@ManyToMany @JoinTable( name="user_brand_access", schema = "auth", joinColumns= @JoinColumn(name="person_id"), inverseJoinColumns= @JoinColumn(name="brand_id") ) private Set<Brand> brands;
当关联表仅包含这两个属性及自动生成的id列时,该实现运行正常。但现在需要为关联表添加记录创建者的userID字段,添加记录时出现如下错误:
2023-01-25 16:56:53 org.postgresql.util.PSQLException: ERROR: record "new" has no field "created_by" 2023-01-25 16:56:53 Where: SQL statement "INSERT INTO logging.history (tabname, schemaname, operation, new_val,created_by) 2023-01-25 16:56:53 VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(NEW),COALESCE(NEW.created_by,NEW.updated_by,'my-user'))"
我推测错误原因是未定义created_by字段。虽然可以通过新建"PersonBrand"实体解决,但会使模型变得复杂。请问能否不新建实体就为该关系添加这个字段?
解答
不行,必须新建中间实体,原因如下:
- JPA的
@ManyToMany仅适用于无附加属性的纯关联关系,当关联表需要额外字段(如created_by)时,这种映射方式无法满足需求。 - 必须将关联表升级为独立实体(比如
PersonBrand):- 在实体中用两个
@ManyToOne注解分别关联Person和Brand - 添加
created_by等附加字段并做好映射 - 将原实体中的
Set<Brand>替换为Set<PersonBrand>,同时在Brand端做对应调整
- 在实体中用两个
你遇到的数据库错误,核心是触发器在插入关联表记录时尝试读取new.created_by,但当前@ManyToMany的映射逻辑不会在插入时填充该字段。只有将关联表转为实体后,才能通过实体属性维护created_by的值,触发器才能正常获取到该字段内容。
内容的提问来源于stack exchange,提问作者Jose Gleeson
相关产品推荐
相关产品推荐

