Lazy loading was often an issue with JPA 2.0. You have to define at the entity if you want to use FetchType.LAZY (default) or FetchType.EAGER to load the relation and this mode is always used. FetchType.EAGER is only used if we want to always load the relation. FetchType.LAZY is used in almost all of the cases to get a well performing and scalable application.
But this is not without drawbacks. If you have to use an element of the relation, you need to make sure, that the relation gets initialized within the transaction that load the entity from the database. This can be done by using a specific query that reads the entity and the required relations from the database. But this will result in use case specific queries. Another option is to access the relation within your business code which will result in an additional query for each relation. Both approaches are far from perfect.
JPA 2.1 entity graphs are a better solution for it. The definition of an entity graph is independent of the query and defines which attributes to fetch from the database. An entity graph can be used as a fetch or a load graph. If a fetch graph is used, only the attributes specified by the entity graph will be treated as FetchType.EAGER. All other attributes will be lazy. If a load graph is used, all attributes that are not specified by the entity graph will keep their default fetch type.
Lets have a look how to define and use an entity graph.