我正在JavaEE
开发一个Web应用程序,我正在使用JPA
命名查询来查询数据库。但是,当我不得不连接具有多个分支的表时,我不知道如何做到这一点,并且我尝试为以下情况构建并执行一些查询,但它总是返回null
。
这是一张描述我情况的图片: IMAGE
我试图使用@NamedQuery
从多个JOIN中选择多个表(实体)中的字段。请注意我从以下类中删除了setter和getters
以减少代码大小。
@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<Vehicle> vehicles = new ArrayList<Vehicle>();
}
@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<FixRequest> fixRequests = new ArrayList<FixRequest>();
}
@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<TroubleJoin> request_Troubles = new ArrayList<TroubleJoin>();
@OneToMany(cascade = CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="fixRequest")
private List<FixJoin> requset_Fixes = new ArrayList<FixJoin>();
@OneToMany(cascade = CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="fixRequest")
private List<Payment> payments = new ArrayList<Payment>();
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<FixJoin> requset_Fixes = new ArrayList<FixJoin>();
}
@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<UnpaidFixRequestObject> getUnpaidFixRequestObjects(long partyID){
TypedQuery<UnpaidFixRequestObject> typedQuery = entityManager.createNamedQuery(FixRequest.getGetNotPaidRequestsByPartyQuery(),UnpaidFixRequestObject.class);
typedQuery.setParameter(FixRequest.getGetNotPaidRequestsByPartyQueryPartyParam(), partyID);
return typedQuery.getResultList();
}
}
@ViewScoped
@ManagedBean
public class PaymentFace {
@EJB
private FootprintEntityFacade<Payment> paymentFacade;
@EJB
QueryFacade queryFacade;
private List<Party> parties;
private List<UnpaidFixRequestObject> unpaidFixRequests;
private String selectedParty = "";
private String selectedFixRequest = "";
private Payment payment;
private boolean showCreditPaymentControls = false;
@PostConstruct
public void init() {
parties = new ArrayList<Party>();
unpaidFixRequests = new ArrayList<UnpaidFixRequestObject>();
parties = queryFacade.getAllParties();
for (Party p : parties) {
p.setName(p.getID() + " - " + p.getName() + " - " + p.getAddress());
}
unpaidFixRequests = queryFacade.getUnpaidFixRequestObjects(parties.get(0).getID());
}
}
任何帮助将不胜感激。 提前谢谢。
答案 0 :(得分:0)
好的尝试此查询,我添加了显式连接:
"Select new org.master.jpa.UnpaidFixRequestObject(v.attributes.type,v.attributes.model,fr.ID,fr.requestDate,SUM(f.cost),SUM(p.paidAmount)) " +
" From FixRequest fr" +
" inner join fr.payments p" +
" inner join fr.vehicle v" +
" inner join v.party pt" +
" inner join fr.requset_Fixes rf" +
" inner join rf.fix f"
" WHERE pt.ID=:partyID " +
" GROUP BY v.attributes.type,v.attributes.model,fr.ID,fr.requestDate"
答案 1 :(得分:0)
编写 @Maciej 的查询并通过将ID从SuperEntity移动到所有其他类来更改模型。
实体层次结构的默认访问类型取决于实体类的属性上的映射注释的放置以及未明确指定访问类型的实体层次结构的映射超类。