I've the following mapping:
#Document
class Event {
Object carbonCopy;
}
carbonCopy has several attributes and its schema is undetermined - various events can have different set of attributes. Assume that carbonCopy has status field. I need to find all Events that have carbonCopy.status equal to NEW. Is it possible with query DSL, how? I'm struggling with various mixes of Path and Expression instances to no avail.
You can use similar like
in terminal
db.events.find({"carbonCopy.status":"NEW"})
in termilnal if you need existance as well
db.events.find({carbonCopy.status:{"$exists":true}},"carbonCopy.status":"NEW"})
NOW when it comes to SDM
Criteria criteria = Criteria.where("carbonCopy.status").is("NEW")
Query query = new Query(criteria);
return mongoTemplate.findOne(query, Event.class);
Criteria criteria = Criteria.where("carbonCopy.status").is("NEW").And("carbonCopy.status").exists(true)
Query query = new Query(criteria);
return mongoTemplate.findOne(query, Event.class);
It's possible with the following piece of code:
QEvent event = QEvent.event;
PathBuilder<Event> query = new PathBuilder<Event>(Event.class, "entity");
BooleanExpression expr = query.getMap("objectCarbonCopy", String.class, String.class).get("status").eq(Expressions.constant("NEW"));
Where QEvent is querydsl generated class.
Related
I have laid out the Java architecture according to my requirement but is struggling with the formation of query part.
The architecture is as follows
Class AbcRequest{
List<Filters> filters;
}
Class Filters{
String abcCode;
List<String> abcType;
}
Class abcController{
getFilters(List<String>someList, boolean status, AbcRequest request){
for(Filters filter: request.getFilters(){
String abcCode = filter.getAbcCode();
List<String> abcTypes = filter.getAbcType();
}
}
}
Now I want to pass these values to a repository and get the list of required queries from DB based on it.
My query should have a condition like :
where ((someList in ('a','b') and status='false' and abcCode='8' and abcType in ('done','pending') OR (someList in ('a','b') and status='false' and abcCode='6' and abcType in ('pending'))
How to write a MongoDB #Query to get such a query out of the repository method.
It is a mixture of many 'AND' along with combination of 'OR'
Like for example :-- where (a AND b AND c AND d) OR (a AND e AND f AND d)
I know how to use simple OR with #Query:- Like building a query for example (where A=10 OR B=10)
#Query('$or' : [{A:10},{B:10}])
But query that I wanted to build is a bit complex and am struggling with it. Also I don't want to use Criteria because I have to deal with return types. Best is to use #Query and I have been instructed to use #Query as well.
Any help will be much appreciated.
Mayme you can try this:
Query query = new Query();
Criteria criteria = new Criteria();
Criteria a = new Criteria();
a.andOperator(Criteria.where("someList").in(Arrays.asList("A","B")),Criteria.where(
"status").is(false),Criteria.where("abcCode").is(6),....)
// B is the same as a
Criteria b = new Criteria();
//...
criteria.orOperator(a,b);
query.addCriteria(criteria);
I found a very good link to answer my own question : writing complex query in mongo DB
This will help with writing complex queries using #Query annotation for MongoDB.
This will also provide a vivid understanding of how to use AND and OR.
Thanks!
How can I create a derived query methods in Spring data which select result based on multiple conditions but with only one parameter.
List<Entity> findById1OrId2OrId3(String id1OrId2OrId3);
Something like this example.
I don't think it is possible with derived queries.
Alternatively,
#Query("from Entity e where e.id1 = ?0 or e.id2 = ?0 or e.id3 = ?0")
List<Entity> findById1OrId2OrId3(String singleId);
You can use "In" and make list of Ids then make a new derived query to achieve this
I have a very complicated query that doesn't convert to HQL, so I must use SQL. I put my query into a NamedNativeQuery annotation. It "should" return a list of two values (List<Object[2]>). When I try to run, the session fails to load the query because I haven't defined a mapping or result class. I cannot create a simple class to map these values to because the annotations have to go in a specific DAO project and the code that is using the queries exists in its own project. (The DAO project is more general-purpose and the entities in that project map directly to tables in our database. I cannot just create a small class in this project to map to my query result because it wouldn't fit the schema of this project)
Is there a way for me to map the query results to a more generic class, or even better is there some way for me to just get a List<Object[]> back without having to map at all to anything particular? This is extremely frustrating that Hibernate has to work in this particular way when all I want to do is execute a query and get the result back as an array.
This is the code that I use for storing the result of a SQL query in a List<Object[]>. Maybe you can adapt it to what you need:
public List<Object[]> executeSelectQuery(String sqlQuery) {
List<Object[]> cleanedResults = new ArrayList<Object[]>();
SQLQuery query = sessionFactory.getCurrentSession().createSQLQuery(sqlQuery);
List<Object[]> hibernateResults = query.list();
// Hibernate does not return always a List<Object[]>, but a list of strings or integers, so it is necessary to check the returned values
if (!hibernateResults.isEmpty()) {
if (hibernateResults.get(0) instanceof Object[]) {
cleanedResults = hibernateResults;
} else {
Object[] row;
// Use a 'for' because 'foreach' sometimes has casting exceptions converting to object
for (int i = 0; i < hibernateResults.size(); i++) {
row = new Object[1];
row[0] = hibernateResults.get(i);
cleanedResults.add(row);
}
}
}
return cleanedResults;
}
A NamedNativeQuery supports an addition annotation to allow you map the result to a POJO:
#SqlResultSetMapping(name="MyResult.Mapping", entities = {
#EntityResult(entityClass=MyResult.class, fields = {
#FieldResult(name="email", column="email"),
#FieldResult(name="name", column="name")
})
})
Then add resultSetMapping="MyResult.Mapping" to your NamedNativeQuery annotation.
I ended up not using NamedNativeQueries because they weren't working for me. Instead, I just used session.createSQLQuery with constant Strings, and it worked.
I probably didn't phrase my question properly. I could not use a #SqlResultSetMapping because I didn't have any classes to map to based on the structure of the code I am working with. My query has to come out as a List<Object[]> result, and there is no way to do that with NamedNativeQueries because Hibernate doesn't support it.
Im new to query dsl.Im using Spring repositories to get the result set.And one case i have to get the maximum of a column and get the fields in to an entity.My predicate code is below.I get error once i run this code.
public static Predicate getMaximum(){
QUserDetails details = QUserDetails.userDetails;
return details.id.eq(details.id.max());
}
And this is how i fetch my resultset using spring jpa
public UserDetails findByCustomerId(Predicate predicate);
And this is the error i get:
org.springframework.data.mapping.PropertyReferenceException: No property find found for type com.example.entity.UserDetails.Can anyone help me acheive what i want here.
You have to define a QueryDslJpaRepository which adds implementation for QueryDslPredicateExecutor
http://docs.spring.io/spring-data/jpa/docs/1.5.0.M1/api/org/springframework/data/jpa/repository/support/QueryDslJpaRepository.html
You can see a tutorial here:
http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-eight-adding-functionality-to-a-repository/
From the QueryDSL email group, apparently what you have to do to select the max ID is this:
from(entity).singleResult(entity.id.max())
So it's
JPAQuery jpaQuery = new JPAQuery(entityManager);
QEntity qEntity = QEntity.entity;
Long maxId = query.from(qEntity).singleResult(qEntity.id.max());
I have a collection of states, that I want to cache for the life of the application, preferably after it is called for the first time. I'm using EclipseLink as my persistence provider. In my EJB3 entity I have the following code:
#Cache
#NamedQueries({
#NamedQuery(
name = "State.findAll",
query = "SELECT s FROM State s",
hints = {
#QueryHint(name=QueryHints.CACHE_USAGE, value=CacheUsage.CheckCacheThenDatabase),
#QueryHint(name=QueryHints.READ_ONLY, value=HintValues.TRUE)
}
)
})
This doesn't seem to do anything though, if I monitor the SQL queries going to MySQL it still does a select each time my Session Bean uses this NamedQuery.
What is the correct way to configure this query so that it is only ever read once from the database, preferably across all sessions?
Edit: I am calling the query like this:
Query query = em.createNamedQuery("State.findAll");
List<State> states = query.getResultList();
The solutions posted here not worked for me. But i've made it work with:
#Cache
#NamedQueries({#NamedQuery(
name = "State.findAll",
query = "SELECT s FROM State s",
hints = {
#QueryHint(name = QueryHints.QUERY_RESULTS_CACHE, value = HintValues.TRUE)
}
)})
Just a guess here, but you might try
query.cacheQueryResults();
after you create it but before you getResultList.
-- MarkusQ
I got EclipseLink 1.0.1 cache to work by adding just the query hint:
Query query = em.createNamedQuery("Person.find");
query.setParameter("NAME", name);
query.setHint("eclipselink.cache-usage", "CheckCacheThenDatabase");
return (Person)query.getSingleResult();
I didn't change the entity at all, and haven't yet tried to configure cache using annotations.