Generating a Hibernate Criteria query from parameters - java

I have to create a query in our backend application using the parameters obtained from the client. Consider this diagram:
I have entities (Type field), those entities' fields (Parameter), a relation, a value and an operand. So in sql terms the table above translates to this:
... WHERE Item.reach_complience = ”<1%”
and Item.technical.type = ”RES”
and Item.technical.value <= ”1k”
and Item.technical.value >= ”4K7”
and (Item.technical.footprint = ”RC0603” or Item.technical.footprint = ”RC0805”)
and Item.classification.incurrent_handling = ”prefered-to-use”
I really don't want to reinvent the weel here, so my question is:
Is there a Criteria factory libarary which uses JPA or more specifically Hibernate or is there some 3rd party library which can be used to create criteria queries? We are using Eclipse RCP on the frontend and data arrives to the backend (Spring) through an Apache Cxf service. I wish to write maintainable using JPA's query syntax.

Yes. I think ISearch is the best: http://code.google.com/p/hibernate-generic-dao/wiki/Search

Related

fetching single column values in JPA

I want to get all the values from a particular column in JPA and store all values into a list. currently, I am using the below approach but I am getting records in something else format.can someone please help me out
Query q1 = factory.createNativeQuery("select * from booking_attendee where booking_id="+id);
List<String> em1=q1.getResultList();
return em1;
query otput
em=[[Ljava.lang.Object;#68606667, [Ljava.lang.Object;#2cd7f99a, [Ljava.lang.Object;#137a5a5, [Ljava.lang.Object;#a45cc1c, [Ljava.lang.Object;#61fdc06d, [Ljava.lang.Object;#72f5eee1, [Ljava.lang.Object;#4e536797]
If you want to create a native query for this, it is more about how to solve this in SQL. You do not say SELECT * which means all columns. You would have to say SELECT your_column_name to select only a specific column.
Query q1 = factory.createNativeQuery("SELECT your_column FROM booking_attendee");
List<String> em1 = q1.getResultList();
The WHERE clause could and should be defined with the parameter binding of JPA. There are several advantages concerning performance and SQL injection.
Named parameter binding is special to the persistence provider (e.g. Hibernate). The common way for JPA is using ? to let your code be portable to other providers.
Query q1 = factory.createNativeQuery("SELECT your_column FROM booking_attendee b WHERE b.booking_id = ?");
q1.setParameter(1, id);
List<String> em1 = q1.getResultList();
Native queries offer the possibilities to use original SQL. Like this, some features which are specific for your database could be used with this. Nevertheless, if you do not have very specific SQL code, you should also have a look in JPQL, the specific query language of JPA, and the JPA Criteria API which offers advantages when you want to refactor your code, shows errors during compile time and makes the dynamic creation of queries easier.

Is there a way to dynamically generate Spring Data Jpa queries?

I'm writing an app using Spring Boot, Spring Data. And I'm trying to implement a filtering feature based on different filter parameters.
Using Spring Data queries we can define quite complex logic, e.g.:
#Query("SELECT u FROM User u WHERE u.status = 1")
Collection<User> findAllActiveUsers();
But what if the number of where clauses, order, limit, number of different parameters are unknown till we make an actual filter request which can be quite complex.
Right now filter params are send in a json object which I parse and retrieve them and the result sql query can be something like this:
SELECT * FROM table
WHERE field1 != `value1` and (field1 != ` value2 `OR (field1 = `value3` AND filed2 < 3))
AND field2 != 99
Is it possible to generate dynamically complex queries with undefined (till the actual filter request, during runtime) number of params, where clauses and other stuff?
I use this active project RSQL for JPA
https://github.com/perplexhub/rsql-jpa-specification
Sometime back I wrote an article on Spring Data JPA Query with Dynamic Where Clause. In this example you can send a Where Clause and Map of parameters for that. You can make use of this and modify it a bit suit your needs.
I would suggest using Spring JPA Specification
ref : https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/
To build it in a type safe manner, you can use FluentJPA.

Get data through Hibernate without Entity classes

We use Hibernate and annotations to map our db and entities. But for some data tables I don't want entity classes (Because these table names and all are keep changing) so that the application will be more dynamic
So is it possible using hibernate to load data from a table without a entity class?
If so how?
Hibernate provides a way to execute SQL query and to map it to an entity or any class : native sql queries.
Use plain JDBC. I'm not sure what you mean by "table names and all are keep changing" but it sounds like a bad idea to me.
What you could do is create the sql query using string concatenation then use plain JDBC to execute it. That way you can keep table names dynamic.
If Persistence class won't be used, then the data encapsulation won't occur thus data can be accessed directly.
Hibernate Queries interact with the POJO class to fetch data.
Query, Criteria, HQL all the classes use the POJO for fetching data.
Hibernate Framework was mainly designed for the ORM Mapping.
Thus without POJO class, not possible to interact with the database.
Thus using JDBC connection would be the option left.
Use Dynamic models introduced in Hibernate 5 version - 5.4.0.Final
Hibernate Dynamic Models
To achieve this you will need HBM files created.
Session s = openSession();
Transaction tx = s.beginTransaction();
Session s = openSession();
// Create a customer
Map david = new HashMap();
david.put("name", "David");
// Create an organization
Map foobar = new HashMap();
foobar.put("name", "Foobar Inc.");
// Link both
david.put("organization", foobar);
// Save both
s.save("Customer", david);
s.save("Organization", foobar);
tx.commit();
s.close();
Here Customer & Organization are table names
Organization is Parent of Customer.
Click on the above link for more details

Filter custom fields not present in database using Apache Cayenne

In my API it is currently possible to filter on all fields that exists in the database.
Filtering is implemented in FilterUtils.java in the API project. This translates the url parameters to a Apache Cayenne search and returns the result to the resource.
In the "Main" project there are generated classes for each database table in com.foo.bar.auto these are extended by classes in com.foo.bar.
The classes in com.foo.bar can have custom functions. An example is Document.getAccount.
Document.getAccount is exposed in the API, but it is not able to filter it because it's not a database field. I need to be able to filter fields like Document.getAccount.
Is it possible to register these functions in Cayenne somehow?
The syntax for searching on custom fields needs to be equal to todays filtering syntax. So when searching for account it should look like this: Document?filter=account(EQ)1234.
Any ideas? All help is appreciated.
Your best bet is to split your filter keys into persistent and non-persistent properties. Then you'd build 2 expressions, one for each subset of keys. Use the first expression to build a query to fetch from DB, and the second one - to filter the returned result in memory:
Expression p = ...
Expression np = ...
SelectQuery query = new SelectQuery(Document.class, p);
List<Document> docs = context.performQuery(query);
List<Document> filteredDocs = np.filterObjects(p);

How Can I Query a DB for ResultSet which is not Mapped into an Entity(JPA, JBoss)

I'm running an application in JBoss and Using JPA.
For a report I need a group by query which I expect to return a result set with the following structure example:
count,idA,idB
I did not find a way to implement this in JPA.
What are my best options for implementing this considering I'm developing in JBoss 5, EJB3
You can use a custom holder class and use the NEW keyword in your query:
SELECT NEW com.mycompany.myapp.MyClass(count, idA, idB)
FROM ...
WHERE ...
Of course, MyClass needs to have the proper constructor defined.
In the case of Native queries, you can create a dummy entity into which the result set can be mapped to (Native query will not be mapped into an Object unless its a real managed entity).
The entity is a dummy as it will not be persisted and it only used for mapping the result set of the native query into this entity.

Categories