J'ai donc une requête de base de données jpa qui fonctionne, et renvoie tous les SiteBmdfBusinessDay de cette table et les relie à leur SiteBmdf correspondant en joignant sur leurs colonnes ID. Ce que je veux faire, c'est, au lieu d'obtenir tous les SiteBmdfBusinessDay, je veux juste obtenir ceux avec le plus récent businessDay.JPA ne sélectionne que les dates les plus récentes par article
Voici la classe SiteBmdfBusinessDay ...
@Entity
public class SiteBmdfBusinessDay extends BaseEntity {
private static final long serialVersionUID = 1L;
private Long id;
private SiteBmdf siteBmdf;
private DateTime businessDay;
private Long failedCount;
private DateTime lastSuccessfulBusinessDay;
private DateTime lastSuccessfulFullBusinessDay;
private Ticket ticket;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "site_bmdf_business_day_site_bmdf_business_day_id_seq")
@SequenceGenerator(name = "site_bmdf_business_day_site_bmdf_business_day_id_seq", sequenceName = "site_bmdf_business_day_site_bmdf_business_day_id_seq", allocationSize = 1)
@Column(name = "site_bmdf_business_day_id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@ManyToOne
@JoinColumn(name = "site_bmdf_id")
public SiteBmdf getSiteBmdf() {
return siteBmdf;
}
public void setSiteBmdf(SiteBmdf siteBmdf) {
this.siteBmdf = siteBmdf;
}
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime", parameters = {
@Parameter(name = "databaseZone", value = "UTC"), @Parameter(name = "javaZone", value = "UTC") })
public DateTime getBusinessDay() {
return businessDay;
}
public void setBusinessDay(DateTime businessDay) {
this.businessDay = businessDay;
}
public Long getFailedCount() {
return failedCount;
}
public void setFailedCount(Long count) {
this.failedCount = count;
}
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime", parameters = {
@Parameter(name = "databaseZone", value = "UTC"), @Parameter(name = "javaZone", value = "UTC") })
public DateTime getLastSuccessfulBusinessDay() {
return lastSuccessfulBusinessDay;
}
public void setLastSuccessfulBusinessDay(DateTime lastSuccessfulBusinessDay) {
this.lastSuccessfulBusinessDay = lastSuccessfulBusinessDay;
}
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime", parameters = {
@Parameter(name = "databaseZone", value = "UTC"), @Parameter(name = "javaZone", value = "UTC") })
public DateTime getLastSuccessfulFullBusinessDay() {
return lastSuccessfulFullBusinessDay;
}
public void setLastSuccessfulFullBusinessDay(DateTime lastSuccessfulFullBusinessDay) {
this.lastSuccessfulFullBusinessDay = lastSuccessfulFullBusinessDay;
}
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "ticket_id")
public Ticket getTicket() {
return ticket;
}
public void setTicket(Ticket ticket) {
this.ticket = ticket;
}
}
Et la classe SiteBmdf ...
@Entity
public class SiteBmdf extends BaseEntity {
private static final long serialVersionUID = 1L;
private Long id;
private String site;
private Long failureCount;
private Set<SiteBmdfBusinessDay> businessDays;
private List<SiteBmdfNote> notes;
private Resolution resolution;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "site_bmdf_site_bmdf_id_seq")
@SequenceGenerator(name = "site_bmdf_site_bmdf_id_seq", sequenceName = "site_bmdf_site_bmdf_id_seq", allocationSize = 1)
@Column(name = "site_bmdf_id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSite() {
return site;
}
public void setSite(String site) {
this.site = site;
}
@Transient
public Long getFailureCount() {
return failureCount;
}
public void setFailureCount(Long failureCount) {
this.failureCount = failureCount;
}
@JsonIgnore
@OneToMany(mappedBy = "siteBmdf", orphanRemoval = true, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public Set<SiteBmdfBusinessDay> getBusinessDays() {
return this.businessDays;
}
public void setBusinessDays(Set<SiteBmdfBusinessDay> businessDays) {
this.businessDays = businessDays;
}
@OneToMany(mappedBy = "siteBmdf", orphanRemoval = true, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
public List<SiteBmdfNote> getNotes() {
Collections.sort(notes);
return notes;
}
public void setNotes(List<SiteBmdfNote> notes) {
this.notes = notes;
}
@ManyToOne
@JoinColumn(name = "resolutionId")
public Resolution getResolution() {
return resolution;
}
public void setResolution(Resolution resolution) {
this.resolution = resolution;
}
}
Et voici la méthode de requête en cours ....
@Override
public PageImpl<SiteBmdfBusinessDay> bmdfSitePaged(UiBuildCriteria criteria) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<SiteBmdfBusinessDay> query = builder.createQuery(SiteBmdfBusinessDay.class);
Root<SiteBmdfBusinessDay> root = query.from(SiteBmdfBusinessDay.class);
if (!criteria.getSearch().getPredicateObject().isEmpty()) {
List<Predicate> predicates = predicateBuilderService.buildPredicates(builder, root, criteria.getSearch());
query.where(builder.and(predicates.toArray(new Predicate[] {})));
}
query.select(root);
builder.max(root.<Long>get("businessDay"));
// get the count for PageImpl
Long total = this.count(criteria);
// Set the order by
List<CustomSort> defaultSorts = new ArrayList<CustomSort>(
Arrays.asList(
new CustomSort("businessDay", Boolean.TRUE),
new CustomSort("siteBmdf.site", Boolean.FALSE)
));
List<Order> orders = sortOrderBuilderService.buildSort(builder, root, criteria.getSort(), defaultSorts);
query.orderBy(orders);
List<SiteBmdfBusinessDay> content = entityManager.createQuery(query).setFirstResult(criteria.getPagination().getStart())
.setMaxResults(criteria.getPagination().getNumber()).getResultList();
return new PageImpl<>(content, criteria.getPageRequest(), total);
}
Donc, comme je l'ai dit, les résultats actuels sont juste tous les éléments de la table SiteBmdfBusinessDay avec leur site correspondant Bmdfs. Je voudrais seulement les SiteBmdfBusinessDays avec le plus récent businessDay pour chaque site.
Par exemple, si j'ai la table site_bmdf_business_day:
site_bmdf_business_day_id | site_bmdf_id | business_day
1 | 1 | 6/1/2011
2 | 2 | 6/1/2011
3 | 1 | 6/6/2011
4 | 3 | 6/6/2011
J'voudrais seulement pour afficher:
site_bmdf_business_day_id | site_bmdf_id | business_day
2 | 2 | 6/1/2011
3 | 1 | 6/6/2011
4 | 3 | 6/6/2011
Je sais que je vais besoin de quelque chose le long des lignes de builder.max (racine .get ("businessDay")) mais je ne sais pas comment l'implémenter.
Toute aide ici serait grandement appréciée.
Notez que this question est similaire, mais pas exactement ce que je cherche car toutes les réponses sont en SQL et j'ai besoin de quelque chose dans jpa ici.
Bien que SQL fonctionne vraiment, alors merci vous pour ça! Cependant, je ne vais pas marquer cela comme résolu pour le moment, au cas où quelqu'un aurait une idée qui fonctionne comme un constructeur, ce dont j'ai vraiment besoin. La chose ici est que, bien que cet ensemble de données spécifique ne devienne pas trop grand, je voudrais utiliser cette implémentation dans des endroits où la table peut être proche de 1M lignes, donc je ne peux pas tirer tout l'ensemble et l'analyser. –
Hélas, mon patron aime le résultat original de toute façon, donc je marque cela comme résolu! –