[英]JPA mapping with two ManyToOne using an intermediary table (middle entity)
I am trying to set a JPA mapping with JoinTable, and it seems to be ignored when Hibernate (my JPA implementation) is doing a query. 我正在尝试使用JoinTable设置JPA映射,当Hibernate(我的JPA实现)正在执行查询时,它似乎被忽略了。
To explain the use case 解释用例
Each time a user gets a page of my app, I insert a line in the USAGE_LOG table (with the id of the user and the id of the page). 每次用户访问我的应用页面时,我都会在USAGE_LOG表中插入一行(带有用户ID和页面ID)。
Each page is related to a category (for instance: settings, orders, items, news...) and a type (for instance create, update, display, delete). 每个页面都与一个类别(例如:设置,订单,项目,新闻...)和一个类型(例如创建,更新,显示,删除)相关。
So, I have some kind of middle entity table, that links a page to: a category + a type. 因此,我有某种中间实体表,该表将页面链接到:类别+类型。 Like a triplet: (page, category, type)
像三元组一样:(页面,类别,类型)
My table structure 我的表结构
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
So the USER_ACTION table is a join table with the particularity that it links a USAGE_LOG_PAGE to a ACTION_CATEGORY and a ACTION_TYPE at the same time. 因此,USER_ACTION表是一个联接表,其特殊性是它同时将USAGE_LOG_PAGE链接到ACTION_CATEGORY和ACTION_TYPE。
Also, I can have several USAGE_LOG_PAGE that are linked to the same ACTION_CATEGORY and ACTION_TYPE. 另外,我可以有多个USAGE_LOG_PAGE链接到相同的ACTION_CATEGORY和ACTION_TYPE。
Unfortunately, I cannot change the database structure (it is legacy code). 不幸的是,我无法更改数据库结构(它是遗留代码)。
I have tried the following Mappping on the Entity "UsageLogPage" 我已经尝试在实体“ 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;
(I use Lombok for @Getter and @Setter) (我将Lombok用于@Getter和@Setter)
This mapping compiles, but when I try to get data, I have the following exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'usagelogpa0_.actionCategory' in 'field list' 编译此映射,但是当我尝试获取数据时,出现以下异常:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:“字段列表”中的未知列“ usagelogpa0_.actionCategory”
Indeed, the Hibernate query is: 实际上,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=?
(the key part is the "actionCategory" and "actionType" in the select) (关键部分是选择中的“ actionCategory”和“ actionType”)
This is not what I expect, Hibernate should do a join. 这不是我期望的,Hibernate应该加入。
Have you any idea of what I did wrong? 您知道我做错了什么吗?
Thanks ! 谢谢 !
After lots of investigations, I have found that: 经过大量调查,我发现:
At the end, even if I couldn't change the database, I could change the object model. 最后,即使我不能更改数据库,也可以更改对象模型。
So I created the middle entity "UserAction", binded it with ManyToOne on the UsageLogPage entity, removed the attribute "actionCategory" and "actionType" from the UsageLogPage and added them as ManyToOne in the new UserAction entity. 因此,我创建了中间实体“ UserAction”,将其与UsageLogPage实体上的ManyToOne绑定,从UsageLogPage中删除了属性“ actionCategory”和“ actionType”,并将它们作为ManyToOne添加到了新的UserAction实体中。
If you have a table that acts as a middle entity for 2 different ManyToOne relationships, perhaps the best solution is to create the middle entity in your object model. 如果您有一个表充当2个不同的ManyToOne关系的中间实体,那么最好的解决方案是在对象模型中创建中间实体。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.