使用中介table(中间实体)的两个 ManyToOne 的 JPA 映射
JPA mapping with two ManyToOne using an intermediary table (middle entity)
我正在尝试使用 JoinTable 设置 JPA 映射,当 Hibernate(我的 JPA 实现)正在执行查询时它似乎被忽略了。
用例说明
每次用户访问我的应用程序页面时,我都会在 USAGE_LOG table 中插入一行(包含用户 ID 和页面 ID)。
每个页面都与一个类别(例如:设置、订单、项目、新闻...)和一个类型(例如创建、更新、显示、删除)相关。
所以,我有某种中间实体 table,它将页面链接到:类别 + 类型。像三胞胎:(页面,类别,类型)
我的table结构
table USAGE_LOG (for information only, this one works well)
ID PrimaryKey
USER_ID Foreign key to column ID of table USER
USAGE_LOG_PAGE_ID Foreign key to column ID of table USER_LOG_PAGE
table USAGE_LOG_PAGE
ID PrimaryKey
URL VARCHAR
USER_ACTION_ID Foreign key to column ID of table USER_ACTION
table USER_ACTION
ID PrimaryKey
ACTION_CATEGORY_ID Foreign key to column ID of table ACTION_CATEGORY
ACTION_TYPE_ID Foreign key to column ID of table ACTION_CATEGORY
table ACTION_CATEGORY
ID PrimaryKey
NAME VARCHAR
table ACTION_TYPE
ID PrimaryKey
NAME VARCHAR
所以 USER_ACTION table 是一个连接 table 具有特殊性它将 USAGE_LOG_PAGE 链接到 ACTION_CATEGORY 和 ACTION_TYPE 同时.
此外,我可以有多个 USAGE_LOG_PAGE 链接到同一个 ACTION_CATEGORY 和 ACTION_TYPE。
不幸的是,我无法更改数据库结构(它是遗留代码)。
我已经在实体上尝试了以下映射 "UsageLogPage"
@ManyToOne
@JoinTable(name="action",
joinColumns=@JoinColumn(name="ID", referencedColumnName="USER_ACTION_ID"),
inverseJoinColumns=@JoinColumn(name="ACTION_CATEGORY_ID", referencedColumnName="ID"))
@Getter @Setter
private ActionCategory actionCategory;
@ManyToOne
@JoinTable(name="action",
joinColumns=@JoinColumn(name="ID", referencedColumnName="USER_ACTION_ID"),
inverseJoinColumns=@JoinColumn(name="ACTION_TYPE_ID", referencedColumnName="ID"))
@Getter @Setter
private ActionType actionType;
(我将 Lombok 用于 @Getter 和 @Setter)
此映射可以编译,但是当我尝试获取数据时,出现以下异常:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:'field list'
中的未知列 'usagelogpa0_.actionCategory'
确实,Hibernate 查询是:
select usagelogpa0_.ID as ID1_80_0_,
usagelogpa0_.actionCategory as actionCa2_80_0_,
usagelogpa0_.actionType as actionTy3_80_0_,
usagelogpa0_.URL as URL5_80_0_
from usage_log_page usagelogpa0_
where usagelogpa0_.ID=?
(关键部分是select中的"actionCategory"和"actionType")
这不是我所期望的,Hibernate 应该做一个连接。
你知道我做错了什么吗?
谢谢!
经过大量调查,我发现:
- 它没有按预期工作,因为我在属性级别放置了@ManyToOne 和@JoinTable 注释。我手工创建了一个getter,并在上面添加了注释,它们被考虑在内
- 它仍然无法正常工作,因为 Hibernate 在 USAGE_LOG_PAGE table 时间 运行 没有找到列 "USER_ACTION_ID"。由于某种原因(我找不到),此列不在可用字段中。在实体 "UsageLogPage" 中添加字段 "usage_action_id" 时,它找到了属性,但拒绝创建映射,因为 USAGE_ACTION_ID 不是主键。
最后,即使我不能更改数据库,我也可以更改对象模型。
所以我创建了中间实体 "UserAction",将其与 UsageLogPage 实体上的 ManyToOne 绑定,从 UsageLogPage 中删除属性 "actionCategory" 和 "actionType" 并将它们添加为 ManyToOne新的 UserAction 实体。
如果您有一个 table 作为 2 个不同 ManyToOne 关系的中间实体,也许最好的解决方案是在您的对象模型中创建中间实体。
我正在尝试使用 JoinTable 设置 JPA 映射,当 Hibernate(我的 JPA 实现)正在执行查询时它似乎被忽略了。
用例说明
每次用户访问我的应用程序页面时,我都会在 USAGE_LOG table 中插入一行(包含用户 ID 和页面 ID)。
每个页面都与一个类别(例如:设置、订单、项目、新闻...)和一个类型(例如创建、更新、显示、删除)相关。
所以,我有某种中间实体 table,它将页面链接到:类别 + 类型。像三胞胎:(页面,类别,类型)
我的table结构
table USAGE_LOG (for information only, this one works well)
ID PrimaryKey
USER_ID Foreign key to column ID of table USER
USAGE_LOG_PAGE_ID Foreign key to column ID of table USER_LOG_PAGE
table USAGE_LOG_PAGE
ID PrimaryKey
URL VARCHAR
USER_ACTION_ID Foreign key to column ID of table USER_ACTION
table USER_ACTION
ID PrimaryKey
ACTION_CATEGORY_ID Foreign key to column ID of table ACTION_CATEGORY
ACTION_TYPE_ID Foreign key to column ID of table ACTION_CATEGORY
table ACTION_CATEGORY
ID PrimaryKey
NAME VARCHAR
table ACTION_TYPE
ID PrimaryKey
NAME VARCHAR
所以 USER_ACTION table 是一个连接 table 具有特殊性它将 USAGE_LOG_PAGE 链接到 ACTION_CATEGORY 和 ACTION_TYPE 同时.
此外,我可以有多个 USAGE_LOG_PAGE 链接到同一个 ACTION_CATEGORY 和 ACTION_TYPE。
不幸的是,我无法更改数据库结构(它是遗留代码)。
我已经在实体上尝试了以下映射 "UsageLogPage"
@ManyToOne
@JoinTable(name="action",
joinColumns=@JoinColumn(name="ID", referencedColumnName="USER_ACTION_ID"),
inverseJoinColumns=@JoinColumn(name="ACTION_CATEGORY_ID", referencedColumnName="ID"))
@Getter @Setter
private ActionCategory actionCategory;
@ManyToOne
@JoinTable(name="action",
joinColumns=@JoinColumn(name="ID", referencedColumnName="USER_ACTION_ID"),
inverseJoinColumns=@JoinColumn(name="ACTION_TYPE_ID", referencedColumnName="ID"))
@Getter @Setter
private ActionType actionType;
(我将 Lombok 用于 @Getter 和 @Setter)
此映射可以编译,但是当我尝试获取数据时,出现以下异常: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:'field list'
中的未知列 'usagelogpa0_.actionCategory'确实,Hibernate 查询是:
select usagelogpa0_.ID as ID1_80_0_,
usagelogpa0_.actionCategory as actionCa2_80_0_,
usagelogpa0_.actionType as actionTy3_80_0_,
usagelogpa0_.URL as URL5_80_0_
from usage_log_page usagelogpa0_
where usagelogpa0_.ID=?
(关键部分是select中的"actionCategory"和"actionType")
这不是我所期望的,Hibernate 应该做一个连接。
你知道我做错了什么吗?
谢谢!
经过大量调查,我发现:
- 它没有按预期工作,因为我在属性级别放置了@ManyToOne 和@JoinTable 注释。我手工创建了一个getter,并在上面添加了注释,它们被考虑在内
- 它仍然无法正常工作,因为 Hibernate 在 USAGE_LOG_PAGE table 时间 运行 没有找到列 "USER_ACTION_ID"。由于某种原因(我找不到),此列不在可用字段中。在实体 "UsageLogPage" 中添加字段 "usage_action_id" 时,它找到了属性,但拒绝创建映射,因为 USAGE_ACTION_ID 不是主键。
最后,即使我不能更改数据库,我也可以更改对象模型。
所以我创建了中间实体 "UserAction",将其与 UsageLogPage 实体上的 ManyToOne 绑定,从 UsageLogPage 中删除属性 "actionCategory" 和 "actionType" 并将它们添加为 ManyToOne新的 UserAction 实体。
如果您有一个 table 作为 2 个不同 ManyToOne 关系的中间实体,也许最好的解决方案是在您的对象模型中创建中间实体。