java JPA 三路连接注解
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12697703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JPA 3-way join annotation
提问by Blessed Geek
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;
}
Any unique single record of process-operation-sequence is obtained by the SQL that has a 3-way join constraint:
process-operation-sequence 的任何唯一单个记录都由具有 3-way join 约束的 SQL 获得:
SELECT *
FROM event e, process p, operation q
WHERE e.processId = p.id
AND e.datetime = q.datetime
AND 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
为了在 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;
}
Where the JPQL specifies the transitive 3rd join constraint:
其中 JPQL 指定了可传递的第三连接约束:
SELECT e FROM Event e
INNER JOIN FETCH e.process p
INNER JOIN FETCH e.operations q
WHERE p.sequence = q.sequence
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:
但是,我希望在实体 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;
}
So that it would not be necessary to specify transitive-join constraint in the JPQL
这样就没有必要在 JPQL 中指定传递连接约束
SELECT e FROM Event e
INNER JOIN FETCH e.process p
INNER JOIN FETCH e.operations q
How do I model a transitive join using JPA annotations?
如何使用 JPA 注释对传递连接建模?
回答by James
You seem to be trying to model a query, instead of your data. You should model your data correctly, then write your query.
您似乎正在尝试为查询建模,而不是为您的数据建模。您应该正确地对数据建模,然后编写查询。
You seem to have
你好像有
Event
事件
- process
- ManyToOne (processId)
- 过程
- 多对一(processId)
Process
过程
- events - OneToMany
- operations - OneToMany
- 事件 - 一对多
- 操作 - 一对多
Operation
手术
- process - ManyToOne (sequence) (this one is a little odd, as sequence is not the Id, this is outside of the JPA spec, but some JPA provider may support it)
- process - 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
To get all the object back use,
为了让所有对象重新使用,
Select o, p, e from Operation o join o.process p join p.events e where e.datetime = o.datetime
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 规范范围内,但某些 JPA 提供程序可能支持它。在 EclipseLink 中,您可以使用 DescriptorCustomizer 来配置任何关系以使用任何表达式标准,或者您拥有 SQL。
回答by Dragan Bozanovic
Your pseudo-mappings are almost the correct solution, you just need to group two @JoinColumn
s in a @JoinColumns
:
您的伪映射几乎是正确的解决方案,您只需要将两个@JoinColumn
s分组到 a 中@JoinColumns
:
@OneToOne
@JoinColumns({
@JoinColumn(
name = "datetime", referencedColumnName="datetime",
insertable=false, updatable=false),
@JoinColumn(
name = "sequence", referencedColumnName="sequence",
insertable=false, updatable=false)
})
private Operation operations;