Custom query with JPA DataTables (jquery Datatables) - java

I'm building a web page where I get a jquery DataTable with a list of rows connected to the id of a field I'm passing through the form.
I'd like to create a DataTable that uses a sort of "native query" using a parameter inside the method of my controller.
Something like:
#Query("Select * from ... where ...=:id ", native="true")
public DataTablesOutput <Object> findByField (#Param(value="id")id, input);
I know it doesn't work, but I haven't understood at all how Specification and QueryDSL work with the DataTable repository, so could someone please make a simple example with objects instead of generics?
(The id I'm passing is a column of the resultSet from the Database, but it's not mapped in the object I get on java, because I'm trying to make the query lighter and nonrecursive)

Related

Access user defined method properties on query - Esper

I implemented a query where i mined data from a database but i have to change it so i mine my data from a custom function in my code. I read the documentation and added the annotation import on the configuration. The query throws that error:
Failed to resolve event type, named window or table by name 'path.to.my.class.customfunction'
I don't know the type that my function have to return but i tried Arraylist and Hashmaps with key an integer and value a custom class and didn't work.
My final query want to look like this :
select * from LocationEvent as loc,
***CustomFuntion()*** as product
where loc.id=product.id ;
I kept the structure i used for database connection. I don't know if there is another way to solve this. Thanks.
EDIT: I managed to make call the custom function with that query :
select path.to.class.getProducts() as product from pattern[every timer:interval(3 sec)]
My function right now return an ArrayList and the query returns this:
[Product{ProductID=124,.....,},Product{...}]
So now my problem is that i can't access properties of Product on the query like products.ProductID
If you want to have a custom function in the from-clause you can use the "method:". The docs have this described here: Accessing Non-Relational Data via Method. The Esper runtime then calls your method to get events/rows.

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.

How to use getById method to get the a corresponding name in Spring MVC?

I'm learning Spring MVC and I want find a car via an id but get in return the name.
In my service class I call a generic method getXXXById. This is something JPA gives me by nature.
I know that I get the whole entity but how can I just receive the corresponding name to the id.
Example: I call getCarById(2) and it gives me back Tesla.
My Table:
id | Name
----------
1 | Ford
2 | Tesla
My Service:
class CarService {
// code ...
public Optional<CarEntity> getCarById(int id) {
return carRepository.findById(id);
}
There are two options to do that.
Making your own query
You could write your own query in JQPL to retrive only names.
For example you could create method like that in your repository.
#Query("select t.name from CarEntity where id = ?1")
public String findNameById(Integer id);
more information on this feature of Spring Data Jpa HERE
Projections
Second option is to make projection. As it is written in documentation
Spring Data query methods usually return one or multiple instances of the aggregate root managed by the repository. However, it might sometimes be desirable to rather project on certain attributes of those types. Spring Data allows to model dedicated return types to more selectively retrieve partial views onto the managed aggregates.
In simple words, it allows you to aggregate your results form queries in some limited set of attributes rather then whole entity.
Specifically for your needs I'd suggest to use first approch, but it is worth to know both.

Hibernate. How to create an empty table from ResultSetMetaData?

I have a ResultSetMetaDataobject.
PreparedStatement ps=con.prepareStatement("select var1, var2 from test1, test2");
ResultSet rs=ps.executeQuery();
ResultSetMetaData rsmd=rs.getMetaData();
System.out.println("Total columns: "+rsmd.getColumnCount());
System.out.println("Column Name of 1st column: "+rsmd.getColumnName(1));
System.out.println("Column Type Name of 1st column: "+rsmd.getColumnTypeName(1));
I need to create an new empty table with all the fields in the above ResultSetMetaData
Open a new connection in different database
Use the meta data above
Create a new empty table with this meta data
I can see two possible solutions
Reflection. In general to create a table with Hibernate, I need to create a bean. But I don't know in advance what fields the ResultSetMetaData will contain . Should I create this bean with reflection?
HQL CREATE TABLE . Is this possible?
What is the simplest way to do this? How can I do this?
Couple of solutions that I can think of:
SchemaExport - Iterate through your ResultSetMetaData which exposes API's like getColumnName and getColumnType to get the information you need. Using this information create a hibernate mapping XML and send it to SchemaExport.create.
// yourClassMapper.xml generated in runtime
Configuration config = new Configuration();
config.addResource("yourClassMapper.xml");
new SchemaExport(config).create(true,true)
Native Query - As Usual Iterate through your metadata to figure out what should the columns be.
Using createSQLQuery or even using createNativeQuery
session.createSQLQuery("create table .....").executeUpdate();
This link provides an explanation on how to create custom fields. You can make use of its DOM Parser for 1st approach or create just tables and use the method mentioned in this blog to create custom fields. (Refer to this class MappingManager and its related custom map configuration)
Lastly, You need 2 different datasource to be configured for this. And inject the second database's source for creating session/sessionfactory in above implementations.
I dont think you need to create bean for it. If you want to create new table with same fields then simple fire this query on database using hibernate or jdbc.
SHOW CREATE TABLE tablename
Now simply change the name of the table in query, can be easily done in Java.
Now you does not need to create any bean for newly created table.
There are two ways for fetching data from table in hibernate. First way is get table data in form of bean object, another way is fire sql query and get data in form of Object (Java Class). you can get data in form of Object and Object Array using hibernate.
When we use join query in hibernate, then there is no specific type of bean is available for handling result of join because it contain column from multiple table so you will get data in form of Object and Object Array.
Just get Data in form of Object or Object Array.
Check This Link of my github... not exactly what you want but still will help :
here
I hope I Helped you.

How do I apply a projection to a Spring Data REST query method resource?

I'm using Spring Data REST 2.1.4.RELEASE.
I created
an entity Booking,
its REST repository (extending CrudRepository) named BookingRepository
and a projection BookingDetails (annotated with #Projection(name="details", types = Booking.class)) for returning some of its linked entities exploded, such as Resource, Activity, Applicant etc.
The client gets all bookings with .../rest/bookings and the JSON response includes links for the linked entities. If it adds ?projection=details then the linked entities are exploded and returned. And this is great.
Now I add this custom method to the repository:
List<Booking> findByApplicant(#Param("applicant") Person applicant);
When the client invokes it with .../rest/bookings/search/findByApplicant?applicant=5, there seem to be no way to request the details projection. Following attempts are ignored:
adding &projection=details to the query string
making the method always return BookingDetails:
List<BookingDetails> findByApplicant(#Param("applicant") Person applicant);
Summarizing, custom search methods (findBy*) never return a projection. Unless you annotate the repository with #RepositoryRestResource(excerptProjection = BookingDetails.class), but this leads to some problems, first of all the client has to always use the same projection. How can we allow the user to use projections also with findBy* methods?
I verfied this working with Spring Data REST 2.2.1, so please update it. Make sure your client actually sends the the requested parameters as you intend. While debugging, I found out that e.g. cURL drops query parameters if you do not explicitly quote the URI. So this:
curl http://localhost:8080/orders/search/findByApplicant?applicant=5&projection=details
will not send any of the query parameters. Once you quote the URI, it will.
curl 'http://localhost:8080/orders/search/findByApplicant?applicant=5&projection=details'
Sort of the same is in place for the increasingly popular HTTPie. With it the required syntax is:
http :8080/orders/search/findByApplicant applicant==5 projection==details
In case you can't get it to work that way, it would be cool to get a running example project to look at.

Categories