本文介绍了JPA 3路联接注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将三个表建模为三个实体:

There are three tables modeled as three entities:

@Entity
@Table(name="event")
public class Event {
  public Long datetime;
  public String name;
  public Long processId;
}

@Entity
@Table(name="process")
public class Process {
  public Long Id;
  public Long sequence;
  public Name name;
}

@Entity
@Table(name="operation")
public class Operation {
  public Long Id;
  public Long datetime;
  public Long sequence;
}

具有三向联接约束的SQL会获取任何唯一的流程-操作序列唯一记录:

Any unique single record of process-operation-sequence is obtained by the SQL that has a 3-way join constraint:

SELECT *
FROM event e, process p, operation q
WHERE e.processId = p.id
  AND e.datetime = q.datetime
  AND p.sequence = q.sequence

要在JPA中实现该功能,我必须列出一系列操作,通过JQPL相等p.sequence = q.sequence

To implement that in JPA, I have to make a list of operations,which would be explicitly narrowed down to a single record thro the JQPL equality p.sequence = q.sequence

@Entity
@Table(name="event")
public class Event {
  public Long datetime;
  public String name;
  public Long processId;
  @OneToOne
  @JoinColumn(
    name = "processId", referencedColumnName="id",
    insertable=false, updatable=false)
  private Process process;

  @OneToMany
  @JoinColumn(
    name = "datetime", referencedColumnName="datetime",
    insertable=false, updatable=false)
  private List<Operation> operations;
}

JPQL在其中指定传递式第三连接约束:

Where the JPQL specifies the transitive 3rd join constraint:

SELECT e FROM Event e
INNER JOIN FETCH e.process p
INNER JOIN FETCH e.operations q
WHERE p.sequence = q.sequence

但是,我希望所有三个约束都在实体POJO中建模.是否应该没有办法单独使用JPA注释进行三向联接?如以下实体伪代码所示:

However, I want all three constraints to be modeled inside the entity POJO. Shouldn't there be way to use JPA annotations alone to three-way join? As the following entity pseudo-code illustrates:

@Entity
@Table(name="event")
public class Event {
  public Long datetime;
  public String name;
  public Long processId;
  @OneToOne
  @JoinColumn(
    name = "processId", referencedColumnName="id",
    insertable=false, updatable=false)
  private Process process;

  @OneToOne
  @JoinColumn(
    name = "datetime", referencedColumnName="datetime",
    insertable=false, updatable=false)
  @JoinColumn(
    name = "process.sequence", referencedColumnName="sequence",
    insertable=false, updatable=false)
  private Operation operations;
}

因此不必在JPQL中指定传递联接约束

So that it would not be necessary to specify transitive-join constraint in the JPQL

SELECT e FROM Event e
INNER JOIN FETCH e.process p
INNER JOIN FETCH e.operations q

如何使用JPA注释为传递联接建模?

How do I model a transitive join using JPA annotations?

推荐答案

您似乎正在尝试为查询而不是数据建模.您应该正确地对数据建模,然后编写查询.

You seem to be trying to model a query, instead of your data. You should model your data correctly, then write your query.

您似乎有

事件

  • 过程
  • ManyToOne(processId)

过程

  • 事件-OneToMany
  • 操作-OneToMany

操作

  • 过程-ManyToOne(序列)(此序列有点奇怪,因为序列不是Id,这超出了JPA规范,但某些JPA提供程序可能会支持它)

要查询事件的所有操作,可以使用

To query all operations for an event, you could use,

Select o from Operation o join o.process p join p.events e where e.datetime = o.datetime

要重新使用所有对象,

Select o, p, e from Operation o join o.process p join p.events e where e.datetime = o.datetime

如果您确实需要将查询建模为关系,则这超出了JPA规范,但某些JPA提供程序可能会支持它.在EclipseLink中,您可以使用DescriptorCustomizer来配置任何关系以使用任何表达式条件,或者您拥有SQL.

If you really need to model the query as a relationship, this is outside of the JPA spec, but some JPA providers may support it. In EclipseLink you can use a DescriptorCustomizer to configure any relationship to use any expression criteria, or you own SQL.

这篇关于JPA 3路联接注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 23:31