In short, JPA ignores Hibernate FetchMode.JOIN
by default. The reason it does this is JPA fetches entities lazily (only when you need it, e.g. when you call getStart()
). As a result, the application reserves resources to only when you need it.
Eager fetching is usually a bad choice and should be avoided, unless you really need to. I would suggest reading this thread as it lists much of the reading materials related to that.
What you could do is use @NamedEntityGraph
to define eager-fetching of your entities. Here, you specify the attributes that you need to fetch eagerly (start
and end
). To read more about this, you can see here and here.
@Entity
@Table(name = "edge")
@NamedEntityGraph(name = "Edge.nodes", attributeNodes = {
@NamedAttributeNode("start"),
@NamedAttributeNode("end")
}) // This is the important annotation
public class Edge {
@EmbeddedId
private EdgeKey id = new EdgeKey();
private int value;
@ManyToOne
@MapsId("startId")
@JoinColumn(name = "start_id", referencedColumnName = "id")
private Node start;
@ManyToOne
@MapsId("endId")
@JoinColumn(name = "end_id", referencedColumnName = "id")
private Node end;
// getters, setters...
}
@Embeddable
public class EdgeKey implements Serializable {
@Column(name = "start_id", nullable = false)
Integer startId;
@Column(name = "end_id", nullable = false)
Integer endId;
// getters, setters, equals and hash code...
}
Furthermore, you annotate your JPA repository method with @EntityGraph
:
@Repository
public interface EdgeRepository extends JpaRepository<Edge, Integer> {
@Override
@EntityGraph(value = "Edge.nodes", type = EntityGraph.EntityGraphType.LOAD)
List<Edge> findAll(); // You override the default implementation of findAll()
@EntityGraph(value = "Edge.nodes", type = EntityGraph.EntityGraphType.LOAD)
Edge getByValue(int value); // other example
}
This will result in a query that's similar to this:
SELECT edge0_.end_id AS end_id1_0_0_,
edge0_.start_id AS start_id2_0_0_,
node1_.id AS id1_1_1_,
node2_.id AS id1_1_2_,
edge0_.value AS value3_0_0_,
node1_.value AS value2_1_1_,
node2_.value AS value2_1_2_
FROM edge edge0_
LEFT OUTER JOIN node node1_ ON edge0_.start_id=node1_.id
LEFT OUTER JOIN node node2_ ON edge0_.end_id=node2_.id