If I am using a Join to create predicates in a criteriaquery I won't get any results. The same predicates are returning entities when I am using the Game table as root.
Working Query:
CriteriaQuery<Game> query = cb.createQuery(Game.class);
Root<Game> root = query.from(Game.class);
List<Predicate> predicates = new LinkedList<Predicate>();
if(!selectedPlatforms.isEmpty()) {
predicates.add(root.get(Game_.type).in(TypeConverter.convert(selectedPlatforms)));
}
if(!selectedCategories.isEmpty()) {
Join<Game, String> collection = root.join(Game_.categories);
predicates.add(collection.in(cb.literal(selectedCategories)));
}
if(!selectedGames.isEmpty()) {
predicates.add(cb.isTrue(root.get(Game_.name).in(selectedGames)));
}
query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
games = em.createQuery(query).getResultList();
Not working query:
CriteriaQuery<Hit> query = cb.createQuery(Hit.class);
List<Predicate> predicates = new LinkedList<>();
Date startDate = null;
Date endDate = null;
Root<Hit> hitRoot = query.from(Hit.class);
switch (time) {
case "Week":
startDate = new DateTime().withWeekOfWeekyear(timeValue).withDayOfWeek(DateTimeConstants.MONDAY).toDate();
endDate = new DateTime().withWeekOfWeekyear(timeValue+1).withDayOfWeek(DateTimeConstants.SUNDAY).toDate();
}
predicates.add(cb.and(cb.greaterThanOrEqualTo(hitRoot.<Date>get("hitDate"), startDate), cb.lessThanOrEqualTo(hitRoot.<Date>get("hitDate"), endDate)));
Join<Hit, Game> gameJoin = hitRoot.join("game", JoinType.LEFT);
if(!selectedPlatforms.isEmpty()) {
predicates.add(gameJoin.get(Game_.type).in(TypeConverter.convert(selectedPlatforms)));
}
if(!selectedCategories.isEmpty()) {
Join<Game, String> collection = gameJoin.join(Game_.categories);
predicates.add(collection.in(cb.literal(selectedCategories)));
}
if(!selectedGames.isEmpty()) {
predicates.add(cb.isTrue(gameJoin.get(Game_.name).in(selectedGames)));
}
query.groupBy(hitRoot.get("hitDate"), hitRoot.get("shop"));
query.orderBy(cb.asc(hitRoot.get("shop")));
query.where(predicates.toArray(new Predicate[predicates.size()]));
List<Hit> results = em.createQuery(query).getResultList();
The following part is responsible for not returning any machting entity. The same part just applied to a Root instead of Join like in the first query is returning machting entites. Without this part everything else is working.
if(!selectedGames.isEmpty()) {
predicates.add(cb.isTrue(gameJoin.get(Game_.name).in(selectedGames)));
}
The problem resolved itself by restarting the application server in 'Run' mode.
Related
I have a function that returns a list of templates(unsorted); can someone tell me how I can get the list in a sorted format?
public List<FormTemplate> listDomainTemplates(Integer id) {
Domain domain = domainService.getDomain(id);
if (domain == null) {
return new ArrayList<>();
}
CriteriaBuilder cb = sessionFactory.getCurrentSession().getCriteriaBuilder();
CriteriaQuery<FormTemplate> query = cb.createQuery(FormTemplate.class);
Root<FormTemplate> application = query.from(FormTemplate.class);
query.select(application);
Predicate predicate = cb.equal(application.get("domain"), domain);
query.where(predicate);
Query<FormTemplate> q = sessionFactory.getCurrentSession().createQuery(query);
return q.getResultList();
}
Please experiment with following:
query.orderBy(cb.asc(application.get(...));
... - should point to FormTemplate field to sort, I suppose.
I have to make a query in criteria api of two tables that is to say I want to select in the query all the fields of the two tables.
Here I leave the models that I want to select (I have the metamodels of each of them) and I give you an example of how to select the data
of each of them in different consultations
public List<Empleado> empleadoB() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Empleado> criteria = cb.createQuery(Empleado.class);
Root<Empleado> member = criteria.from(Empleado.class);
criteria.select(member).orderBy(cb.asc(member.get(Empleado_.p_ap)));
return em.createQuery(criteria).getResultList();
}
public List<Empleado2> empleadosNom() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Empleado2> criteria = cb.createQuery(Empleado2.class);
Root<Empleado> member = criteria.from(Empleado.class);
Root<Tipo_docs> tDoc = criteria.from(Tipo_docs.class);
Root<Estad_civil> eCivil = criteria.from(Estad_civil.class);
Root<Profesiones> prof = criteria.from(Profesiones.class);
Root<Eps> eps = criteria.from(Eps.class);
Root<Pensiones> pens = criteria.from(Pensiones.class);
Root<Usuario> useri = criteria.from(Usuario.class);
Root<Cargos> cargo = criteria.from(Cargos.class);
criteria.select(cb.construct(Empleado2.class, member.get(Empleado_.id_emp),
member.get(Empleado_.p_ap), member.get(Empleado_.s_ap),
member.get(Empleado_.nombre), member.get(Empleado_.tipo_doc),
member.get(Empleado_.numero_doc), member.get(Empleado_.lugar_exp),
member.get(Empleado_.fecha_nac), member.get(Empleado_.lugar_nac),
member.get(Empleado_.estadocivil), member.get(Empleado_.direc),
member.get(Empleado_.tel), member.get(Empleado_.profesion),
cb.selectCase() .when(cb.isNull(member.get(Empleado_.matricula_prof)), "No Registrado") .otherwise(member.get(Empleado_.matricula_prof)),
member.get(Empleado_.mail),member.get(Empleado_.eps),
cb.selectCase() .when(cb.isNull(member.get(Empleado_.pensiones)), (long)0) .otherwise(member.get(Empleado_.pensiones)),
cb.selectCase() .when(cb.isNull(member.get(Empleado_.usu)), "No Existe") .otherwise(member.get(Empleado_.usu)),
tDoc.get(Tipo_docs_.desc_tdoc),
eCivil.get(Estad_civil_.desc_ecivil), prof.get(Profesiones_.nombre_prof),
eps.get(Eps_.nom_eps),
cb.selectCase() .when(cb.isNull(member.get(Empleado_.pensiones)), "No Aplica") .otherwise(pens.get(Pensiones_.nom_pension)),
cargo.get(Cargos_.id_cargo), cargo.get(Cargos_.desc_cargo) ));
criteria.where(cb.and(cb.equal(member.get(Empleado_.tipo_doc), tDoc.get(Tipo_docs_.id_entidad)),
cb.equal(member.get(Empleado_.estadocivil), eCivil.get(Estad_civil_.id_ecivil)),
cb.equal(member.get(Empleado_.profesion), prof.get(Profesiones_.id_prof)),
cb.equal(member.get(Empleado_.eps), eps.get(Eps_.id_eps)),
cb.or(cb.equal(member.get(Empleado_.usu), useri.get(Usuario_.usuario)), cb.isNull(member.get(Empleado_.usu))),
cb.or(cb.equal(member.get(Empleado_.pensiones), pens.get(Pensiones_.id_pension)), cb.isNull(member.get(Empleado_.pensiones))) ));
criteria.distinct(true);
return em.createQuery(criteria).getResultList();
}
I'm having issues properly grouping my query using CriteriaBuilder and Predicates.
I want to create a query that can generate something like:
SELECT * from tableName where columnA = '1234' and (columnB Like '%33%' or columnB Like '%44%')
But what I'm getting (Obviously expected looking at the code) is:
SELECT * from tableName where columnA = '1234' and columnB Like '%33%' or columnB Like '%44%'
Which does not produce the same result as the first query.
Been trying to work around it, but this is my first time working with criteriaBuilder and predicates.
Here's the code:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Foo> criteriaQuery = builder.createQuery(Foo.class);
Root r = criteriaQuery.from(Foo.class);
Predicate predicate = builder.conjunction();
for(Map.Entry<String, String> entry : searchParams.entrySet()){
if((entry.getKey().equalsIgnoreCase("columnK") || entry.getKey().equalsIgnoreCase("columnY") ||
entry.getKey().equalsIgnoreCase("columnZ") || entry.getKey().equalsIgnoreCase("columnJ")) && !Strings.isNullOrEmpty(entry.getValue())){
predicate = builder.and(predicate,
builder.like(r.get(entry.getKey()),
String.format("%%%s%%", entry.getValue().toString())));
}
else if(entry.getKey().equalsIgnoreCase("theDate") && !Strings.isNullOrEmpty(entry.getValue())){
predicate = builder.and(predicate, builder.equal(r.get(entry.getKey()), entry.getValue()));
}
}
//here's where the problem is ... I realize I can use IN, but I also didn't get that to work
boolean isFirstDone = false;
for(String oneId: idStringList){
if(!isFirstDone) {
predicate = builder.and(predicate, builder.equal(r.get("acceptorId"), oneId));
isFirstDone = true;
}
else{
predicate = builder.or(predicate, builder.equal(r.get("acceptorId"), oneId));
}
}
criteriaQuery.where(predicate);
Thank you.
Okay, so I just cracked this after carefully reading this answer https://stackoverflow.com/a/9323183/5038073 The solution is not exactly what I needed but it helped... a lot
I created a path and combined it with my predicate.
Here's what changed:
This:
boolean isFirstDone = false;
for(String oneId: idStringList){
if(!isFirstDone) {
predicate = builder.and(predicate, builder.equal(r.get("acceptorId"), oneId));
isFirstDone = true;
}
else{
predicate = builder.or(predicate, builder.equal(r.get("acceptorId"), oneId));
}
}
became:
Path<Object> path = r.get("acceptorId");
CriteriaBuilder.In<Object> in = builder.in(path);
for (String oneId: idStringList) {
in.value(oneId);
}
predicate = builder.and(predicate, in);
Pretty simple for all the trouble it took me to solve.
Hope this helps someone else too!
I am trying to add multiple 'and' conditions to criteria in Spring Data but not able to figure out what am I doing wrong.
Please refer the following code :
Criteria criteria = new Criteria();
criteria.andOperator(Criteria.where("siteCode").is(siteCode));
if(paymentMode != null) {
criteria.andOperator(Criteria.where("paymentMode").is(paymentMode));
}
if(planCode != null) {
criteria.andOperator(Criteria.where("packageCode").is(planCode));
}
if(status){
criteria.andOperator(Criteria.where("expiryDateTime").gt(new Date()));
} else {
criteria.andOperator(Criteria.where("expiryDateTime").lte(new Date()));
}
Query query = new Query(criteria);
List<UserPackage> userPackageList = mongoTemplate.find(query, UserPackage.class);
I found out what I was doing wrong. You don't need to use method 'andOperator' and another Criteria inside.
It would simply work by using 'and' method and then chain the following operator method you want to use.
Sharing the working solution to help other newcomers like me.
Criteria criteria = new Criteria();
criteria = criteria.and("siteCode").is(siteCode);
if (paymentMode != null) {
criteria = criteria.and("paymentMode").is(paymentMode);
}
if (planCode != null) {
criteria = criteria.and("packageCode").is(planCode);
}
if (status) {
criteria = criteria.and("expiryDateTime").gt(new Date());
} else {
criteria = criteria.and("expiryDateTime").lte(new Date());
}
Query query = new Query(criteria);
Just in case if you want to add conditions for a date between and match another field, below is what I used.
Criteria criteria = Criteria.where("date").gte(from).andOperator(Criteria.where("date").lt(to));
if (StringUtils.isNotBlank(manager)) {
criteria = criteria.and("manager").is(manager);
}
I use spring-data-elasticsearch framework to get query result from elasticsearch server, the java code like this:
public void testQuery() {
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withFields("createDate","updateDate").withQuery(matchAllQuery()).withPageable(new PageRequest(0,Integer.MAX_VALUE)).build();
List<Entity> list = template.queryForList(searchQuery, Entity.class);
for (Entity e : list) {
System.out.println(e.getCreateDate());
System.out.println(e.getUpdateDate());
}
}
I get the raw query log in server, like this:
{"from":0,"size":10,"query":{"match_all":{}},"fields":["createDate","updateDate"]}
As per the query log, spring-data-elasticsearch will add size limit to the query. "from":0, "size":10, How can I avoid it to add the size limit?
You don't want to do this, you could use the findAll functionality on a repository that returns an Iterable. I think the best way to obtain all items is to use the scan/scroll functionality. Maybe the following code block can put you in the right direction:
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchAllQuery())
.withIndices("customer")
.withTypes("customermodel")
.withSearchType(SearchType.SCAN)
.withPageable(new PageRequest(0, NUM_ITEMS_PER_SCROLL))
.build();
String scrollId = elasticsearchTemplate.scan(searchQuery, SCROLL_TIME_IN_MILLIS, false);
boolean hasRecords = true;
while (hasRecords) {
Page<CustomerModel> page = elasticsearchTemplate.scroll(scrollId, SCROLL_TIME_IN_MILLIS, CustomerModel.class);
if (page != null) {
// DO something with the records
hasRecords = (page.getContent().size() == NUM_ITEMS_PER_SCROLL);
} else {
hasRecords = false;
}
}