JPA 3路连接注释

Ble*_*eek 11 java orm jpa jpql

有三个表被建模为三个实体:

@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;
}
Run Code Online (Sandbox Code Playgroud)

具有3向连接约束的SQL可以获得任何唯一的process-operation-sequence单条记录:

SELECT *
FROM event e, process p, operation q 
WHERE e.processId = p.id
  AND e.datetime = q.datetime
  AND p.sequence = q.sequence
Run Code Online (Sandbox Code Playgroud)

为了在JPA中实现它,我必须列出一个操作列表,这些操作将明确地缩小到JQPL相等的单个记录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;
}
Run Code Online (Sandbox Code Playgroud)

JPQL指定传递的第3个连接约束:

SELECT e FROM Event e
INNER JOIN FETCH e.process p
INNER JOIN FETCH e.operations q
WHERE p.sequence = q.sequence
Run Code Online (Sandbox Code Playgroud)

但是,我希望所有三个约束都在实体POJO中建模.难道不能单独使用JPA注释进行三向连接吗?如下面的实体伪代码所示:

@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;
}
Run Code Online (Sandbox Code Playgroud)

因此,没有必要在JPQL中指定传递连接约束

SELECT e FROM Event e
INNER JOIN FETCH e.process p
INNER JOIN FETCH e.operations q
Run Code Online (Sandbox Code Playgroud)

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

Jam*_*mes 2

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

你似乎有

事件

  • 过程
  • 多对一(进程ID)

过程

  • 事件 - 一对多
  • 操作-OneToMany

手术

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

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

Select o from Operation o join o.process p join p.events e where e.datetime = o.datetime
Run Code Online (Sandbox Code Playgroud)

要重新使用所有对象,

Select o, p, e from Operation o join o.process p join p.events e where e.datetime = o.datetime
Run Code Online (Sandbox Code Playgroud)

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

  • 请接受我的歉意 - 但你能否重新调整你的答案来回答我的问题,而不是建议我如何清除人们扔给我的生活碎片?谢谢。 (5认同)