How to write a Spring jpa query using group by clause without using #Query annotation?
seems its not possible as there is no method name support for it - judging by "Supported keywords inside method names" table in docs http://docs.spring.io/spring-data/jpa/docs/1.7.0.RELEASE/reference/html/
Query annotation is made just for that, use it for custom solutions.
Related
I'm trying to query a spring-data couchbase repository using N1QL queries. I have two doubts:
I'm using #Query annotation to generate queries, my code looks like this:
#Query("#{#n1ql.selectEntity} WHERE $0 = $1 AND #{#n1ql.filter}")
public Page<GsJsonStore> matchJson(String term, String value, Pageable pageable);
//Query
Page<GsJsonStore> p = repo.matchJson("_object.details.status", "ready", pg);
This query doesn't return any results. However, when I run the same query (below) in cbq I get the desired result:
select * from default where _object.details.status = 'ready';
How can I view the query string generated by the Couchbase repository? I'm using spring-boot. Am I correct in using the #Query annotation for this use-case?
Also, how can I perform n1QL queries on CouchbaseOperations template? I know that there's a findByN1QL method, but I didn't find any good documentation about it. Could someone please explain how to use this?
The query looks ok. You did persist your GsJsonStore entities using the Spring Data Couchbase repository did you?
In order to log all the queries generated and executed by the framework (including inline queries like in your case), you can configure the logger like so in a logback.xml configuration:
<logger name="org.springframework.data.couchbase.repository.query" level="debug"/>
You'll see that the query that got executed and the query that you ran in cbq are not the same, since at least you didn't use a WHERE clause.
In CouchbaseOperations there are two methods relative to N1QL queries:
findByN1QL: this expects specific structure of the query, in order to make sure all data necessary to correct deserialization of a Spring Data annotated entity is selected (which is the purpose of the #n1ql.selectEntity and #n1ql.filter SpEL).
findByN1QLProjection is more free-form. If Jackson can deserialize the results of the provided query to the requested Class, then it will. As such, the SELECT clause is much less implicitly restricted in this method.
To use both, you must pass in a N1qlQuery object from the SDK. Such queries can be constructed using factory methods of the N1qlQuery class, for example:
//a version of the query that is constructed from positional parameters
N1qlQuery queryWithParameter = N1qlQuery.parameterized("SELECT name FROM `beer-sample` WHERE name LIKE $0", JsonArray.from("%dog%"));
//let Spring Data execute the query, projecting to the String class
List<String> beerNamesContainingDog = template.findByN1QLProjection(queryWithParameter, String.class);
I'm using spring-ldap 2.0.4 and spring-data-jpa 1.9.0.
I built a JPA repository like this :
public interface PersonRepo extends LdapRepository<Person> {
Person findByUid (String uid);
#Query("(&(attribute=*{0}*)(attribute2=X)(attribute3=Y))")
List<Person> findByAttributeContains(String attribute);
}
So far everything is fine. I could write methods that fill my needs thanks to query methods.
For some queries i had to use #Query annotation because they were many and operator.
But i would like to limit the number of result to return from my second query method.
I know there is there is the Top and First keywords to define query methods in spring JPA. But I didn't manage to get it work. Plus I want to use multiple and operator in the method.
Thanks
I managed to limit the number of result using XML LDAP configuration.
<ldap:ldap-template context-source-ref="contextSource" count-limit="100"/>
I know there is an option in Hibernate to filter entites based on an #Filter annotation!
Is there an option for a JPA 2.0 version of this (i am interested in mainly non-programmatic way -> declarative e.g. persistance.xml option or annotation option)
The goal:
In our application we want to filter all entites whose attribute Active is False or 0.
And do not love to write 30 or more specific selects for this!
I hope it has a more clear way to achieve this!
The perfect functionality would be #Filter and #FilterJoinTable, referenced this answer:
Filter list contained in entity returned by jpa/hibernate query
After some investigation i may say there is no option in JPA to get a filter function with Annotation.
The closest ones to this is:
Criteria API (http://www.objectdb.com/java/jpa/query/criteria)
Manual written query (entityManager createQuery() or createNativeQuery()) for getting entites. (http://www.objectdb.com/java/jpa/query/execute)
However I think it is a missing and very needed functionality :(
As it is mentioned in this document
http://en.wikibooks.org/wiki/Java_Persistence/Advanced_Topics#Filters
How to acheive filtering data?This is nothing to do with inheritance.I want to restrict my object mapping to only subset of rows based on some condition.
There is no standard JPA support for this.
If you are using EclipseLink, you can either use #AdditionalCriteria, or #Multitenent,
see,
http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_additionalcriteria.htm#additionalcriteria
http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_multitenant.htm#BABIEJGD
You could also use a view in the database.
Is it possible to add an OrderBy clause in to JPA Named query at runtime?
Named queries are processed by the persistence provider when the EntityManagerFactory is created. You can't change/modify/append anything about a named query dynamically at runtime.
If you are using JPA 2.0 and you need a way to do high-performance dynamic queries at runtime, you should look into the Criteria API.
From Java EE 5 Documentation : "Is used to specify a named query in the Java Persistence query language, which is a static query expressed in metadata. Query names are scoped to the persistence unit".
As it says, it is static & you can't change the query at runtime.
Rather use custom query or if ordering element is fixed then you can use annotation;
Field:
#OrderBy(value="nickname")
List<Person> friends;
Method:
#OrderBy("nickname ASC")
public List<Person> getFriends() {...};
Even if you can't add order-by clause to your named query, you can provide a parametric orderBy. The following is a perfectly valid query:
SELECT u FROM User u ORDER BY :orderBy
And you are going to change ordering with something like:
query.setParameter("orderBy", "id");