JPA - SpringData - Column 1 equals column 2 - spring

I have a spring-boot project with Spring-Data. I want to do a query like:
SELECT * FROM my_table WHERE column_1 = column_2
How can I do it using the SpringData JpaRepository? I tried to find a way like:
MyTable findByColumn1...Column2() without any luck

There is no default way to do that you have to use the #Query annotation like this:
#Query("select e from entity e where e.column1 = e.column2")
List<Entity> findByColumn1EqualsColumn2();

If you wanna use default method only you can use
List<Entity> findByColumn1AndColumn2(#Param("column1") String column1, #Param("column2") String column2);
And then passing the same parameter for column1 and column 2
i.e.
String column= "abc";
List<Entity> entitylist=repository.findByColumn1AndColumn2(column,column);

Related

List of multiple column condition in query (kind of batch)

when trying to search with single record then this query works
#Query(value = "select * from table t where t.column1 = :column1 and t.column2 = :column2 and t.column3 = :column3")
Flux<Invoice> findByMultipleColumn(#Param("column1”) String column1, #Param("column2”) String column2, #Param("column3”) String column3);
But when I have list of criterias instead of a single row condition then I have to loop over the list of criterias & call the above query multiple times which is not feasible solution.
Sudo code
for (Criteria criteria : criteriaList) {
repository.findByMultipleColumn(criteria.getColumn1(), criteria.getColumn2(), criteria.getColumn3());
}
What I am trying to find a way to solve the above query for multiple LIST of all the 3 column criteria pair, something like below (this is not working solution)
#Query(value = "select * from table t where t.column1 = :column1 and t.column2 = :column2 and t.column3 = :column3")
Flux<Invoice> findByMultipleColumn(#Param List<Table> table);
Is there any way somehow we can try to achieve the above case?
Would be doable if column1, 2 and 3 were Embedded, then you could do
#Query(select * from Entity where embeddedProperty in (:values))
Flux<Entity> findByEmbeddedPropertyIn(Collection<EmbeddedClas> values);
Which would generate the following native SQL clause
Where (column1, column2, column3) in ((x, y, z), ...)
If you don't want to pack these fields i to an embeddable class, you can also try to do a workaround
#Query(select * from Entity where Concat(column1, ';', column2, ';', column3) in (:parametersConcatrenatedInJava)
Flux<Entity> findBy3Columns(Collection<String> parametersConcatrenatedInJava);
It's ofcourse not bulletproof, all three columns could have ";" as their values, this might be problematic if their type is not string, etc.
Edit.:
Third option is to use specification api. Using the criteria builder you can concatenate multiple and / or queries. And pass that specification as an argument to the repository that extends JpaSpecificationExecutor (if you're fetching whole entities) or an entity manager if you're using projections. Read more about specifications

Spring MVC, Select Special Columns in Native SELECT Query

this is my native SELECT Query in Repository
#Modifying
#Query(value = "SELECT * FROM tasks WHERE title LIKE '%Java%' ORDER BY id DESC ", nativeQuery = true)
List<Task> listAllTasks();
this works ok, but when I use custom column name instead of *, like this
#Modifying
#Query(value = "SELECT title FROM tasks WHERE title LIKE '%Java%' ORDER BY id DESC ", nativeQuery = true)
List<Task> listAllTasks();
I have this error :
org.postgresql.util.PSQLException: The column name id was not found in this ResultSet.
any Help?
The resultset doesn't have the "id" in it, you have to provide it.
You should change the way you are declaring your SQL:
SELECT t.title, t.id FROM tasks t WHERE t.title LIKE '%Java%' ORDER BY t.id DESC
Check out this sort example:Native Queries
Select * from Entity -> returns a List of Entity
Example:
#Query(select * from tasks)
List<Task> findAllTasks();
Select column from Entity -> returns a List of Types of the entity.
Example:
#Query(select t.title from tasks t)
List<String> findTitle_AllTasks();
title is of the type String
Select multiple columns from Entity -> returns an Object[] holding the data
Example:
#Query(select t.id, t.title from tasks t)
List<Object[]> findIdTitle_AllTasks();
So, you are retrieving String type data - title and asking to return a List of Task type. This is causing the problem. You can actually check the hibernate docs under HQL and JPQL to understand this.
Plus, you are doing a SELECT (DQL operation). #Modifying is rudimentary here as it is used for DML operations using Data JPA - UPDATE/DELETE.

HQL Select New doesn't return row when a foreign key is null

I have the following named query
#NamedQuery(name = "UserFlight.getUserFlightDetails",
query = "SELECT new com.foobar.UserFlightDetails(uf.flight.divertedAirport, uf.flight.number) " +
"FROM UserFlight uf WHERE uf.user.id=?1 AND uf.flight.id=?2")
The UserFlightDetails constructor is as follows
public UserFlightDetails(Airport airport, String flightNumber) {
this.setDivertedAirport(airport);
this.setFlightNumber(flightNumber);
}
divertedAirport is a foreign key in the flight table, path=(uf.flight.divertedAirport)
My problem is when divertedAirport is null (it's a nullable foreign key), my HQL query returns null as the result (The code doesn't even trigger the constructor above), so I don't get the flightNumber which is never null.
If the divertedAirport isn't null, I get both the airport and the flight number fine (and the above constructor gets executed just fine).
What could be causing this and how could I resolve it? I tried some null functions like nullif and coalesce but nothing helped.
I'm using spring boot 1.2.7, hibernate-core 4.3.11.Final
Probably, the problem is the uf.flight.divertedAirport. This expression do a JOIN between flight and divertedAirport but, as you say, divertedAirport is a fk and can be null.
So, you need to use the LEFT JOIN.
I would rewrite your query like this:
#NamedQuery(name = "UserFlight.getUserFlightDetails",
query =
"SELECT new com.foobar.UserFlightDetails(divertedAirport, flight.number)
FROM UserFlight uf
JOIN uf.flight flight
LEFT JOIN flight.divertedAirport divertedAirport
JOIN uf.user user
WHERE user.id = ?1 AND flight.id = ?2 ")
I remove the references like uf.user.id for a explicit JOIN (JOIN uf.user user plus user.id), because is more legible and this kind of problem that generated your question is more easy to find using this way to write JPQL queries.

spring jpa handling null value in max query

I'm trying to select a sequence id from the database using this query:
#Query("select max(pi.sequence) + 1 from ProductImage pi where pi.product = :product")
int nextSequenceForProduct(#Param("product")Product product);
It works well except when there's no values in the table, it throws some type of null value exception from the JPA code.
Is there a way to handle null values in spring jpa? For example something like this SQL:
select ifnull(max(pi.sequence),1) from ....
you can use nvl() function and change the query to native query or named native query to avoid the exception
#NativeQuery("select nvl(max(pi.sequence),0) + 1 from ProductImage pi where pi.product = :product")

Set array of values to SQL query

I'm using JDBC, I have to set array of values to a single column,
I know it works in Hibernate and Ibatis but it seems to be hard to get it working Pure JDBC sql.
I have an array of String values
names[] = new String[]{"A","B","C"};
and a Query like
select * from emp where name in(?)
I tried pstmt.setObject(1,names), it is not working..
This is not supported in pure JDBC. You have to generate a query so that the in clause contains one placeholder for each element of the array.
Spring's JDBC helper classes support named parameters and what you want to do.
This will work with the following Syntax:
"SELECT * FROM emp WHERE name IN ( SELECT column_value FROM TABLE( ? ) )"
pmst.setArray( 1, conn.createArrayOf( "VARCHAR", names ) );

Resources