基于其他两个实体映射相关的 JPA 实体映射

Posted

技术标签:

【中文标题】基于其他两个实体映射相关的 JPA 实体映射【英文标题】:JPA Entity Mapping which is related based on two other entity mappings 【发布时间】:2015-10-03 04:21:00 【问题描述】:

不确定这是否可行,但尝试根据下面实体中的其他两个实体映射 WorkActionClassWorkflowInstance 映射相关的 WorkflowInstancePlayer player

public class Action implements Serializable 
@Id
private Long action_id;

@ManyToOne
@JoinColumn(name = "work_action_class_id", referencedColumnName = "work_action_class_id")
private WorkActionClass workActionClass;

@ManyToOne
@JoinColumn(name = "workflow_instance_id", referencedColumnName = "workflow_instance_id")
private WorkflowInstance workflowInstance;

UPDATE: How can I map to a WorkflowInstancePlayer player?????
 @ManyToOne
 @JoinColumns( 
        @JoinColumn(name = "workflow_instance_id", referencedColumnName = "workflow_instance_id", insertable = false, updatable = false),
        @JoinColumn(name = "workActionClass.role_class_id", referencedColumnName = "role_class_id", insertable = false, updatable = false)
)
 private WorkflowInstancePlayer player;

workflowInstancePlayer 是基于workflow_instance_idrole_class_id 派生的,但role_class_id 实际上是workActionClass 映射到(workActionClass.role_class_id) 上方的属性

public class WorkflowInstancePlayer implements Serializable 
@Id
private WorkflowInstance workflowInstance;

@Id
private RoleClass roleClass;

@ManyToOne
@JoinColumn(name = "badge", referencedColumnName = "badge")
private Employee employee;

public class WorkActionClass implements Serializable 
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "trx_seq")
private Long work_action_class_id;

@ManyToOne
@JoinColumn(name = "role_class_id")
private RoleClass roleClass;

示例数据为:

Action
------
Id = 10
work_action_class_id = 7
workflow_instance_id = 2


WorkActionClass
---------------
Id = 7
role_name = reviewer
role_class_id = 3


WorkflowInstancePlayer
----------------------
workflow_instance_id = 2
role_class_id = 3
badge = 111222

所以在 Action Entity 中,我会知道 Workflow Instance Player 是 ID 为 111222 的 Employee,而无需将徽章实际存储在 Action 表中。

更新

根据 Vlad 的帖子,我将其调整为

@ManyToOne(fetch=FetchType.LAZY)
   @JoinColumnsOrFormulas(
   @JoinColumnOrFormula(formula=@JoinFormula(value="(SELECT a.role_class_id FROM (Use Table Name not Entity Name here) a WHERE a.work_action_class_id = work_action_class_id)", referencedColumnName="role_class_id")),
   @JoinColumnOrFormula(column = @JoinColumn(name="workflow_instance_id", referencedColumnName="workflow_instance_id"))
)

【问题讨论】:

badge = 111222 是 workflow_instance_id( = 2) 和 role_class_id ( = 3) 的一些函数 - 对吗?....如果不是,你如何得出 badge = 111222? 并非如此。这是一个工作流应用程序。员工 111222 在工作流中被指定为审阅者。审阅者将根据工作流类型执行许多操作。 Oracle 序列号 2 是工作流实例 ID 的下一个内联,审阅者角色的 role_class_id 为 3。因此这三个值被插入到 WorkflowInstancePlayer @NickJI 我重读了你的评论。如果您的意思是“关系”中的功能,那么是的。起初,我将其读作“一个公式”,如 instance_id 乘以 role_class_id 除以 .... 等。这种关系在 WorkflowInstancePlayer 表中定义 要访问 Employee,您需要访问 WorkflowInstancePlayerId,但来自 RoleClass 或 WorkflowInstance,因此您需要遍历一对多 - 没有什么可以告诉您哪个是正确的 WorkflowInstancePlayerId - 所以我认为这种特殊的方法行不通。 什么是变通方法?我在想@Transient 然后手动映射?? 【参考方案1】:

试试这个映射:

@ManyToOne
@JoinColumn(
    name = "workflow_instance_id", 
    referencedColumnName = "workflow_instance_id",
    insertable = false, 
    updatable = false
)
private WorkflowInstance workflowInstance;

@ManyToOne
@JoinColumnOrFormula(
    formula = @JoinFormula(
            value="(SELECT a.work_action_class_id FROM WorkActionClass a WHERE a.role_class_id = role_class_id)", 
        referencedColumnName = "work_action_class_id"
    )
)
private WorkActionClass workActionClass;

@ManyToOne
@JoinColumns( 
    @JoinColumn(
        name = "workflow_instance_id", 
        referencedColumnName = "workflow_instance_id"),
    @JoinColumn(
        name = "role_class_id", 
        referencedColumnName = "role_class_id")
)
private WorkflowInstancePlayer player;

【讨论】:

您的@JoinColumnOrFormula 提供了帮助。看我的帖子,我相信公式应该在 WorkflowInstancePlayer 映射上。事情编译并且我的表看起来按预期创建,但现在我得到 ORA-01799:检索时列可能没有外连接到子查询。 太棒了。对于该错误,使关联 LAZY 并确保您不 JOIN FETCH 它,以允许 Hibernate 使用辅助查询检索它。 嗯,我确实点击并投了赞成票,然后添加了我的评论。在 IE 中提交的评论挂了,所以我复制到剪贴板,刷新页面并再次粘贴。赞成票也必须超时。让我试试 LAZY 看看能不能把这个 Q 关掉 谢谢。我希望它可以帮助。 不错。在 WorkflowInstancePlayer 我添加了@ManyToOne(fetch=FetchType.LAZY)。我不得不修改连接公式以使用实际的表名而不是实体“SELECT a.role_class_id FROM WF_WORK_ACTION_CLASS”与“SELECT a.role_class_id FROM WorkActionClass”,它可以工作。谢谢!

以上是关于基于其他两个实体映射相关的 JPA 实体映射的主要内容,如果未能解决你的问题,请参考以下文章

JPA相关注解

如何使用 JPA Criteria API 连接不相关的实体

如何使用 JPA 和 Hibernate 连接两个不相关的实体

如何在同一个数据库表上映射两个 JPA 或 Hibernate 实体

将同一JPA实体多次映射到其他JPA实体

springBoot整合JPA