pass NULL to SQL query - java

I am getting null result through QueryRunner, but if I execute the query I am getting rows retruned in SQL developer.
ProductId: null
SKUCode:61334a
ServiceResult<List<T>> market = service.getMarketProduct(null,'61334a');
The above mentioned service code will hit DAO layer shown below:
return QueryHelper.queryList( GET_PRODUCTS, new Object[]{ 0 == ProductId? null : ProductId, SKUCode}, this.cs, CPCMarketProductVO.class );
GET_PRODUCTS= SELECT * FROM table WHERE ProductId= nvl(?, ProductId) AND prd_id = nvl(?, SKUCode).
Can someone please tell me why I am getting null results through java code and how results are returned in SQL developer.

I think you are a bit confused in what NVL function is for. Pratically it is useful when the query returns a NULL value and you are doing some kind of operation or aggregate function in it. Instead you are using it to create the request.
Probably you should change the GET_PRODUCTS query in something like
GET_PRODUCTS= SELECT * FROM table WHERE ProductId = ? AND prd_id = ?
When you substitute the ? values with the new Object[]{ 0 == ProductId? null : ProductId, SKUCode} and values ProductId = null, SKUCode = 61334a the query becomes:
GET_PRODUCTS= SELECT * FROM table WHERE ProductId = null AND prd_id = 61334a
returning an empty result set, which should be correct if ProductId is not nullable (I assume is a primary key).
If you instead have NULL ProductIds in your table the result set may not be empty.

Related

Postgres Query returning empty result set from Java

String query = "SELECT distinct on (l->>'test_id') l->>'test_id' test_id,
l->>'result' result,l->>'indication' indication
FROM Ltable,
jsonb_array_elements(lines) with ordinality a(l) WHERE pat_id = ?
AND result_received <= ? AND (l->>'test_id' = ? OR l->>'test_id' = ? )
and archived = false ORDER BY l->>'test_id', result_received DESC LIMIT 2";
jdbcTemplate.query(query, rs -> {
while(rs.next()){
}
}val1, val2, val3, val4);
The above query when executed from pgAdmin returns some rows but when executed from a java app returns an empty resultSet, the line while(rs.next()) never gets entered.
I have logged the query parameters to make sure the correct data is being passed into the query.
Please help look at at and let me know if there's a mistake I'm making somewhere.

Passing optional parameter to JdbcTemplate

I have an issue with JdbcTemplate when passing parameters objects with null reference.
Given that I have the following test data:
jdbcTemplate.execute("INSERT INTO TEST_TABLE VALUES (1,'TEST')");
jdbcTemplate.execute("INSERT INTO TEST_TABLE VALUES (2,'TEST_2')");
jdbcTemplate.execute("INSERT INTO TEST_TABLE VALUES (3, NULL)");
Following code doesn't retrieve anything:
String contentArg = null;
List<Entity> entityList_3 = jdbcTemplate.query("SELECT * FROM TEST_TABLE WHERE CONTENT = ?", new BeanPropertyRowMapper<>(Entity.class), contentArg);
Is there any way I could fix this, just using JdbcTemplate.
Use Oracle NVL function to support optional parameter:
WHERE CONTENT = NVL(?, CONTENT) "
I've been able to solve this by modifying the query.
In my case, I was using IBM solidDb and the fix contains in using IFNULL function.
AND IFNULL(CONTENT,'') = IFNULL(?,'')

Spring Data JPA #query tag is not validating null values with Postgres DB

#Query("from PrsBookingProcess pbp where (:bookingOwnerCode='' OR pbp.bookingOwnerCode = :bookingOwnerCode)"
+ "and (pbp.crtDttime BETWEEN :fromDate AND :toDate)"
+ "and (:bookingProcStatus is null OR pbp.bookingProcStatus = :bookingProcStatus)"
List<PrsBookingProcess> findByPnrbydateRangeandOperator(
#Param("bookingOwnerCode") String bookingOwnerCode,
#Param("fromDate") Calendar fromDate,
#Param("toDate") Calendar toDate,
#Param("bookingProcStatus") String bookingProcStatus);
This is my JPA query to hit Postgres DB. My bookingOwnerCode value takes null only if I check there value with empty quotes(''). If i check by making them :BookingOwnerCode is null and giving them null from UI it will not fetch me records.
As in case of bookingProcStatus. If i do not give any value in UI and run for above query it will not fetch me anything until and unless i give some value to it.
I am using PGAdmin3 for postgrep and JPA for querying.
You could just use :bookingOwnerCode is null OR :bookingOwnerCode = '' instead of just :bookingOwnerCode = ''.
Or you could write a unit/integration test that verifies the expected behaviour.

Java Hibernate a conditional Criterion based on nullability of property is possible?

I have a simple query like this.
select id,status,c01,c02,c03 from mytable
where
criterion1
and criterion2
and criterion3
I need to add another filter like this
//In Java
if(mytable.status=1){
criteria.add(Restrictions.eq("anotherFilter",anotherFilterValue));
}
But the status value comes in the query i mean i can filter in memory but i would like to be able to filter in the DB directly
Like the ordering using case can i use some approach to make it?
Like
select id,status,c01,c02,c03 from mytable
where
criterion1 = ?
and criterion2 = ?
and criterion3 = ?
and
case status is null
? anotherFilter = :valueToFilter
: 1=1//IS NOT NULL NOTHING TO DO..
This can help you.
select id,status,c01,c02,c03 from mytable
where
criterion1 = ?
and criterion2 = ?
and criterion3 = ?
and
((status is null and anotherFilter = :valueToFilter)
or (status is not null))
For criterion api
//In Java
criteria.add(
Restrictions.or(
Restrictions.isNotNull("status"),
Restrictions.and(
Restrictions.eq("anotherFilter",anotherFilterValue),
Restrictions.isNull("status")
)
)
);

SimpleJdbcTemplate and null parameters

I'm using SimpleJdbcTemplate and MapSqlParameterSource in the folowing way:
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
parameterSource.addValue("typeId", typeId, Types.BIGINT);
List<Long> ids = _jdbcTemplate.query(_selectIdByParameters, new EntityIdRowMapper(), parameterSource);
When typeId ( which is a Long ) is null, then the query looks in the following way:
SELECT id FROM XXX WHERE typeId = null
whereas I would expect it to generate
SELECT id FROM XXX WHERE typeId IS NULL
I've reported this issue and the response was that
You will have to provide the appropriate SQL statement based on your query parameters.
and as a consequence my code is littered with null checks.
Is there a more elegant way of handling null parameters sent to the SimpleJdbcTemplate?
They have a point - JdbcTemplate isn't a SQL interpreter, it just replaces your placeholders.
I suggest you construct your clause with a utility method, and concat it to the query string:
String createNullCheckedClause(String column, Object value) {
String operator = (value == null ? "is" : "=");
return String.format("(%s %s ?)", column, operator);
}
...
String query = "select * from table where " + createNullCheckedClause("col", x);
Not very pretty. Alternatively, perhaps you can configure MySQL to allow "= NULL", but I don't think that's an option.

Categories