title: How to join tables with multiple branches in JPA NamedQuery
body: <p>I am developing a web application in <code>JavaEE</code> where i am using <code>JPA</code> <strong>Named Queries</strong> to query against the database. However, i don't know how to do that when having to join tables with multiple branches, and i tried to build and execute some queries for the following situation but it all always returns <code>null</code>.</p>
  
  <p>Here is an image that describes my situation:
  <a href="https://i.stack.imgur.com/tKj1b.png" rel="nofollow noreferrer">IMAGE</a></p>
  
  <p>where i am trying to select field from multiple tables(Entities) with multiple JOIN using <code>@NamedQuery</code>.Please note that i removed setters and <code>getters</code> from the below classes to reduce code size.</p>
  
  <pre><code>@MappedSuperclass
  @EntityListeners({Logger.class})
  public abstract class SuperEntity  implements Serializable,HasName{
  
      @Transient
      private static final long serialVersionUID = -6420076371961889265L;
  
      @Id
      @SequenceGenerator(initialValue = 0, allocationSize = 1, name = "IdGenerator")
      @GeneratedValue(strategy=GenerationType.SEQUENCE,generator = "IdGenerator")
      private long ID;
  
      @Version
      private long version;
  }
  
  
  
  
              @Entity
              public class Party extends SuperEntity {
  
                  @Length(min = 1, max = 30, message = "Invalid party name.")
                  private String name;
  
                  @Enumerated(EnumType.STRING)
                  @NotNull
                  private PartyType type;
  
                  @Length(min = 1, max = 13, message = "Invalid phone number")
                  private String phone;
  
                  @Email(message = "Invalid email address.")
                  @NotNull
                  private String email;
  
                  @NotNull
                  @NotEmpty(message = "Party address is required.")
                  private String address;
  
                  @Valid
                  @OneToMany(cascade = CascadeType.ALL, mappedBy = "party", fetch = FetchType.EAGER)
                  private List&lt;Vehicle&gt; vehicles = new ArrayList&lt;Vehicle&gt;();
  
          }
  
                  @Entity
              public class Vehicle extends SuperEntity {
  
                  @Valid
                  @Embedded
                  private VehicleAttributes attributes;
  
                  @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE})
                  @JoinColumn(name = "partyID")
                  private Party party;
  
                  @Valid
                  @OneToMany(cascade = CascadeType.ALL, mappedBy = "vehicle",fetch=FetchType.EAGER)
                  private List&lt;FixRequest&gt; fixRequests = new ArrayList&lt;FixRequest&gt;();
             } 
  
  
              @NamedQuery(name = FixRequest.GET_NOT_PAID_REQUESTS_BY_PARTY_QUERY, query = "Select new org.master.jpa.UnpaidFixRequestObject(v.attributes.type,v.attributes.model,fr.ID,fr.requestDate,SUM(f.cost),SUM(p.paidAmount)) From Vehicle v,FixRequest fr,Payment p,Fix f,FixJoin fj WHERE v=fr.vehicle AND fr=p.fixRequest AND fr=fj.fixRequest AND fj.fix=f AND v.party.ID=:partyID GROUP BY v.attributes.type,v.attributes.model,fr.ID,fr.requestDate")
              @Entity
              public class FixRequest extends SuperEntity implements Serializable {
  
              @Transient
              static final String GET_NOT_PAID_REQUESTS_BY_PARTY_QUERY = "getNotPaidRequestsByParty";
              @Transient
              static final String GET_NOT_PAID_REQUESTS_BY_PARTY_QUERY_PARTY_PARAM = "partyID";
                  @NotNull
                  @Temporal(TemporalType.TIMESTAMP)
                  private Date requestDate;
  
                  @NotNull
                  @Temporal(TemporalType.DATE)
                  private Date requestedFixDate;
  
                  @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE})
                  @JoinColumn(name = "vehicleID")
                  private Vehicle vehicle;
  
                  @OneToMany(cascade = CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="fixRequest")
                  private List&lt;TroubleJoin&gt; request_Troubles = new ArrayList&lt;TroubleJoin&gt;();
  
                  @OneToMany(cascade = CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="fixRequest")
                  private List&lt;FixJoin&gt; requset_Fixes = new ArrayList&lt;FixJoin&gt;();
  
                  @OneToMany(cascade = CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="fixRequest")
                  private List&lt;Payment&gt; payments = new ArrayList&lt;Payment&gt;();
  
                  private String details;
          }
  
          @Entity
          public class FixJoin extends SuperEntity implements Serializable {
  
              public FixJoin() {
                  super();
              }
  
              @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE})
              @JoinColumn(name = "fixRequestID")
              private FixRequest fixRequest;
  
              @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE})
              @JoinColumn(name = "fixID")
              private Fix fix;
  
              private String details;
          }
  
          @Entity
          public class Fix extends SuperEntity implements Serializable {
  
              @NotEmpty
              @NotNull
              private String type;
  
              @NotEmpty
              @NotNull
              private String detail;
  
              @Column(precision = 2)
              @Min(value = 1)
              private double cost;
  
              @OneToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.LAZY,mappedBy="fix")
              private List&lt;FixJoin&gt; requset_Fixes = new ArrayList&lt;FixJoin&gt;();
          }
  
          @Entity
          public class Payment extends SuperEntity implements Serializable {
  
              @Transient
              private static final long serialVersionUID = 1L;
  
              @Column(precision = 2)
              private double paidAmount;
  
              @Enumerated(EnumType.STRING)
              private PaymentMethod paymentMethod;
  
              private int checkNumber;
  
              private String bank;
  
              private String payer;
  
              private String reciever;
  
              private String notes;
  
              @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE})
              @JoinColumn(name = "fixRequestId")
              private FixRequest fixRequest;
          }
  
          @Stateless
          public class QueryFacade {
  
              @PersistenceContext
              EntityManager entityManager;
  
  
          public List&lt;UnpaidFixRequestObject&gt; getUnpaidFixRequestObjects(long partyID){
              TypedQuery&lt;UnpaidFixRequestObject&gt; typedQuery = entityManager.createNamedQuery(FixRequest.getGetNotPaidRequestsByPartyQuery(),UnpaidFixRequestObject.class);
              typedQuery.setParameter(FixRequest.getGetNotPaidRequestsByPartyQueryPartyParam(), partyID);
              return typedQuery.getResultList();
          }
          }
  
          @ViewScoped
          @ManagedBean
          public class PaymentFace {
  
              @EJB
              private FootprintEntityFacade&lt;Payment&gt; paymentFacade;
  
              @EJB
              QueryFacade queryFacade;
  
              private List&lt;Party&gt; parties;
              private List&lt;UnpaidFixRequestObject&gt; unpaidFixRequests;
  
              private String selectedParty = "";
              private String selectedFixRequest = "";
              private Payment payment;
  
              private boolean showCreditPaymentControls = false;
  
              @PostConstruct
              public void init() {
                  parties = new ArrayList&lt;Party&gt;();
                  unpaidFixRequests = new ArrayList&lt;UnpaidFixRequestObject&gt;();
  
                  parties = queryFacade.getAllParties();
                  for (Party p : parties) {
                      p.setName(p.getID() + " - " + p.getName() + " - " + p.getAddress());
                  }
              unpaidFixRequests = queryFacade.getUnpaidFixRequestObjects(parties.get(0).getID());
          }
      }
  </code></pre>
  
  <p>Any help would be appreciated.
  Thanks in advance.</p>