I am using Spring Data JPA with postgresql as data base.Want to search a pattern using user given keyword
#Query(value = "SELCET * FROM table_name WHERE column_name LIKE (CONCAT('%',:pattern,'%'))")
List<Class> findPattern(String pattern);
but :pattern is not replacing with pattern value
You may try binding the entire LIKE expression to a single placeholder:
#Query(value = "SELECT * FROM table_name WHERE column_name LIKE :pattern")
List<Object[]> findPattern(String pattern);
The usage would be something like this:
String value = "blah";
String pattern = "%" + value + "%";
List<Object[]> rs = repo.findPattern(pattern);
Since like %pattern% is the same as contains pattern, your use case doesn't even need a query coded:
List<MyClass> findByColumnNameContaining(String pattern);
i created domain in postgres:
create domain arrayofids as numeric[];
Now i want to use the domain in spring data like this:
String fakeQuery = "unnest(CAST (:ids AS arrayofids))";
Query nativeQuery = entityManager.createNativeQuery(fakeQuery);
BigInteger[] arrayOfids = new BigInteger[] {new BigInteger("1"),new BigInteger("2)} //or It can be List. It is not important
nativeQuery.setParameter("ids", arrayOfids);
List resultList = nativeQuery.getResultList();
Of course i get Error:
org.postgresql.util.PSQLException: ERROR: cannot cast type bytea to arrayofIds
Before i used https://dalesbred.org/docs/api/org/dalesbred/datatype/SqlArray.html and it worked fine or did custom types in JDBC myself. Hibernate doesn't allow use my domain easy.
Query like that:
select * from mtTbale where id in :ids
is not interested. I should use the domain with unnest and CAST
Make :ids as a text representation of an array of numbers, i.e. "{1, 2}" and add SELECT to the query.
Try this:
String fakeQuery = "SELECT unnest(CAST (:ids AS arrayofids))";
Query nativeQuery = entityManager.createNativeQuery(fakeQuery);
String arrayOfids = "{" + 1 + ", " + 2 + "}"; // obtain the string as is relevant in your case
nativeQuery.setParameter("ids", arrayOfids);
List resultList = nativeQuery.getResultList();
and the second query should look like this:
select * from mtTbale where id = ANY(CAST(:ids AS arrayofids));
You may also use Postgres shorthand (and more readable) cast syntax.
Instead of CAST(:ids AS arrayofids) use :ids::arrayofids.
I am trying to fetch data using native query method. I am able to fetch data using spring data JPA repository declared methods (findAll() etc) and using JPQL Queries.
When I am using Native query method , "select * from" is working. But when I am specifying "select username from " method is not working. Means When specifying column name, it is not working.
I am adding my code like this,
#Query(value = "select u.username from users u" , nativeQuery = true)
List<Users> findByUsername();
But the query using select * from users is working with no problem. Is this native query nature? Or is there any limited type of format the provider defines?
I think the problem is with your return variable.
When you run "*select * from...*" query, you can return list of Users.
However, you want to fetch a column which is probably a varchar, so that you should return List of String:
#Query(value = "select u.username from users u" , nativeQuery = true)
List<String> findByUsername();
I am trying to call a stored procedure, which is built in mysql, in my Spring boot app using JPA. My stored procedure returns the result which cant be contain in single model as it fetches data from combination of tables.
I can do this with "call " but i guess that is not JPA's way. COuld you please let me know what is the best way to do it?
In case you're using plain JPA you need to do a native query call. Something like below.
Query q = em.createNativeQuery("select my_store_pro(?, ?)");
List<Object[]> results = q.getResultList();
for (Object[] a : results) {
System.out.println("result " + a[0] + " " + a[1]);
}
If you're using Spring Data repositories then you want something like below.
#Query(nativeQuery = true, value = "select my_store_pro(?, ?)")
Date callMyStoreProc(int val1, int val2);
Using spring data JPA, I am trying to make this sort of query (it is more complex, this is a simple case)
#Query(nativeQuery = true,
value = "SELECT * FROM events WHERE typeId IN (?1)")
List<Event> findEventsByType(List<Integer> types);
When I launch the query, an exception raises:
org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of java.util.ArrayList. Use setObject() with an explicit Types value to specify the type to use.
I have tried List < Integer >, Integer[], Object[] and String but it is not working...
Can't I pass list of values?
Which is the best approach to make this sort of queries?
Thanks!
Try taking away the #Query and make the method name:
public List<Event> findByTypeIn(List<Integer> types);
See table 2.2 in the link: http://docs.spring.io/spring-data/jpa/docs/1.2.0.RELEASE/reference/html/
I tried like below and it works for me.
#Query(value = "select * from events where type_id in :types", nativeQuery = true)
List<Event> findEventsByType(#Param("types") List<Integer> types);
#Query(value = "SELECT c from Company c where " +
"c.companyName IN (:company_names)")
List<Company> findCompaniesByName(#Param("company_names") List<String> companyNames);
This is the solution to your problem.
Here I am passing List which contains company names and I am querying DB and storing result in List.
Hope this hepls!
Use JPQL. A native query is or should be passed to the database exactly as you have created the SQL string, and unless your driver can take a serialized collection and understand that the single parameter needs to be interpreted as many, it just won't work. The collection you pass in needs the SQL expanded from (?) to (?, ?,...) based on the number of elements in a collection, and JDBC drivers just are not able to do this, and JPA providers are required to execute the string as is.
A JPQL query allows the JPA provider to create the SQL it needs dynamically based on the list passed in, so it can expand the collection for you.
Try this. It will work for Native Query in SpringBoot JPA:
#Query(value = "SELECT * FROM table WHERE columnName IN (:inputList)" ,
nativeQuery = true)
List<Object> findByObjectList(#Param("inputList") List<Object> inputList);
And also in case of JPA, try the below :
List<Object> findByObjectList(List<Object> inputList)
I know this is a little bit out of context (we use Update and not Select), but this can be usefull for others :
/**
* Update the state of list of entities using their ids
* #param ids request ids
* #param state new state
* #return
*/
#Modifying
#Query(value = "UPDATE AbstractRequest SET state = :state WHERE id IN (:ids)")
int updateStates(#Param("ids") List<Long> ids, #Param("state") InternalRequestStep state);
pass array this way inside IN Clause
#Query(value = "select name from teams where name in :names", nativeQuery = true)
List<String> getNames(#Param("names") String[] names);
Call this way
String[] names = {"testing team","development team"};
List<String> teamtest = teamRepository.getNames(names);
Remove brackets around (?1) parameter. Your query value should look like that:
#Query(value = "SELECT * FROM events WHERE typeId IN ?1")
try querying like this:
#Query(nativeQuery = true,
value = "SELECT * FROM events WHERE typeId = ?1")
List<Event> findEventsByType(List<Integer> types);
did it work?