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:
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
@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:
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:
@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
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?
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
Operation
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.