Using the new JPA 2.1 stored procedure call, is there any way to pass a null parameter?
Here is an example usage:
StoredProcedureQuery storedProcedur
We can use Empty string, that will also work as null. eg. select NVL('','XXX') from dual; returns XXX Try to pass StringUtils.EMPTY as parameter.
Yes, it is possible to pass null params to stored procedures when using JPA StoredProcedureQuery.
You have to add the following property in application.properties file and register the parameters with their name.
spring.jpa.properties.hibernate.proc.param_null_passing=true
Example:
StoredProcedureQuery q = em.createStoredProcedureQuery(Globals.SPROC_PROBLEM_COMMENT2, ProblemCommentVO.class);
q.registerStoredProcedureParameter("Patient_ID", Long.class, ParameterMode.IN);
q.registerStoredProcedureParameter("Param2", Long.class, ParameterMode.IN);
q.registerStoredProcedureParameter("Param3", Long.class, ParameterMode.IN);
q.registerStoredProcedureParameter("Param4", Integer.class, ParameterMode.OUT);
q.setParameter("Patient_ID", patientId);
q.setParameter("Param2", null);//passing null value to Param2
q.setParameter("Param3", null);
List<ProblemCommentVO> pComments = q.getResultList();
Integer a = (Integer) q.getOutputParameterValue("Param4");
Simple answer is Yes, it is possible to pass null params to stored procedures when using JPA StoredProcedureQuery.
There are few ways to achieve this. Mainly the solution depends on the hibernate version you are using.
Hibernate 4.3+
Session session = em.unwrap(Session.class);
ProcedureCall procedure = session.createStoredProcedureCall(Constants.MY_PROCEDURE_NAME);
q.registerStoredProcedureParameter("Patient_ID", Long.class, ParameterMode.IN).enablePassingNulls(true);
q.registerStoredProcedureParameter("Param2", String.class, ParameterMode.IN).enablePassingNulls(true);
q.registerStoredProcedureParameter("Param3", Long.class, ParameterMode.IN).enablePassingNulls(true);
q.registerStoredProcedureParameter("Param4", Integer.class, ParameterMode.OUT);
q.setParameter("Param1", patientId);
q.setParameter("Param2", null);//passing null value to Param2
q.setParameter("Param3", null);//passing null value to Param3
List<> results = q.getResultList();
Integer a = (Integer) q.getOutputParameterValue("Param4");
Older Versions
You have to add the following property in application.properties file and register the parameters with their name.
spring.jpa.properties.hibernate.proc.param_null_passing=true
Example:
StoredProcedureQuery q = em.createStoredProcedureQuery(Constants.MY_PROCEDURE_NAME, ResultData.class);
q.registerStoredProcedureParameter("Patient_ID", Long.class, ParameterMode.IN);
q.registerStoredProcedureParameter("Param2", String.class, ParameterMode.IN);
q.registerStoredProcedureParameter("Param3", Long.class, ParameterMode.IN);
q.registerStoredProcedureParameter("Param4", Integer.class, ParameterMode.OUT);
q.setParameter("Param1", patientId);
q.setParameter("Param2", null);//passing null value to Param2
q.setParameter("Param3", null);//passing null value to Param3
List<> results = q.getResultList();
Integer a = (Integer) q.getOutputParameterValue("Param4");
add the following property to your config persistance
hibernate.proc.param_null_passing=true
To go around the issue, if we dont have many possible null parameters to the sproc we can have multiple @NamedStoredProcedureQuery mapping to same sproc in DB. We can then prepare appropriate query.
For example,
@NamedStoredProcedureQuery(name = "MyEntity.GetWithoutNullParam", procedureName = "dbo.GetProc", parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, name = "id", type = Integer.class)},
resultClasses = MyEntity.class),
@NamedStoredProcedureQuery(name = "MyEntity.GetWithNullParam", procedureName = "dbo.GetProc", parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, name = "id", type = Integer.class),
@StoredProcedureParameter(mode = ParameterMode.IN, name = "nullableparam", type = String.class),
resultClasses = MyEntity.class)
Now doing a null check on "nullableparam" we can create appropriate named proc in repository. Something similar to
if(MyEntity.nullableparam == null){StoredProcedureQuery storedProcedureQuery = em.createNamedStoredProcedureQuery("MyEntity.GetWithoutNullParam");}
else{StoredProcedureQuery storedProcedureQuery = em.createNamedStoredProcedureQuery("MyEntity.GetWithNullParam");}
This worked for me
if (columnname.length() > 0) {
fSignUp.setString(3, columnname);
} else {
fSignUp.setNull(<position>, Types.NULL);
}