Reputation: 61
Salam,
I have a problem with (key, value) entity searching.
I don't figure out how to write the jpql query to search.. this is my problem
I have document entity, mapped to oneToMany "MetaData" entity
@Entity
public class Document implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="id_document")
private Integer idDocument;
@Column(name="date_enregistrement")
private Timestamp dateEnregistrement;
// other columns
//bi-directional many-to-one association to MetaData
@OneToMany(mappedBy="document")
private List<MetaData> metaData;
/*
getters and setters
*/
}
and MetaData entity
@Entity
@Table(name="meta_data")
public class MetaData implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="id_meta_data")
private Integer idMetaData;
@Column(name="key")
private String key;
@Column(name="value")
private String value;
//bi-directional many-to-one association to Document
@ManyToOne
@JoinColumn(name="id_document")
private Document document;
/*
getters and setters
*/
}
What i want to do is to search for documents by providing some metadata as parameters.
examples:
Find documents where sender (key = sender) is Youssef (value = Youssef) And receiver (key) is Hamza (value)
it's possible that the client provides more than two parameters.
Thanks in advace
Upvotes: 1
Views: 469
Reputation: 608
As key-value pairs can vary in number, I'll suggest to go with CriteraQuery for more flexibilty:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Document> query = criteriaBuilder.createQuery(Document.class);
Root<Document> root = query.from(Document.class);
Join<Document, MetaData> metadataJoin = root.join("metaData", JoinType.INNER);
List<Predicate> predicateList = new LinkedList<Predicate>();
//If a map contains all your key value pairs
for(Map.Entry<String, String> entry : keyValueMap.entrySet()){
predicateList.add(
criteriaBuilder.and(
criteriaBuilder.equal(metadataJoin.get("key"), entry.getKey()),
criteriaBuilder.equal(metadataJoin.get("value"), entry.getValue())
)
);
}
query.where(criteriaBuilder.or(
predicateList.toArray(new Predicate[predicateList.size()]))
)
query.groupBy(root.get("idDocument"));
query.having(criteriaBuilder.equal(criteriaBuilder.count(root.get("idDocument")), predicateList.size()));
List<Document> documentList = entityManager.createQuery(query).getResultList();
Upvotes: 1