JDBC Feeder : NullPointerException seems to occure when some of my data are null

Hello,

I am trying to use JDBCFeeder to get data from our Oracle database using Gatling 1.5.3.
However, I encounter an issue which seems to occure when some records have null values in columns i retrieve.

For example, I try to build my feeder using “select column1, column2 from table” as request, and having following records :
COLUMN1, COLUMN2
value1 , value2
value3 , null

I get the following NPE :

Exception in thread “main” java.lang.NullPointerException
at com.excilys.ebi.gatling.jdbc.feeder.database.JdbcFeederSource$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$3.apply(JdbcFeederSource.scala:35)
at com.excilys.ebi.gatling.jdbc.feeder.database.JdbcFeederSource$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$3.apply(JdbcFeederSource.scala:35)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:233)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:233)
at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:34)
at scala.collection.mutable.ArrayOps.foreach(ArrayOps.scala:38)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:233)
at scala.collection.mutable.ArrayOps.map(ArrayOps.scala:38)
at com.excilys.ebi.gatling.jdbc.feeder.database.JdbcFeederSource$$anonfun$apply$1$$anonfun$apply$2.apply(JdbcFeederSource.scala:35)
at com.excilys.ebi.gatling.jdbc.feeder.database.JdbcFeederSource$$anonfun$apply$1$$anonfun$apply$2.apply(JdbcFeederSource.scala:35)
at scala.collection.Iterator$$anon$19.next(Iterator.scala:401)
at scala.collection.Iterator$class.foreach(Iterator.scala:772)
at scala.collection.Iterator$$anon$19.foreach(Iterator.scala:399)
at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:48)
at scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:102)
at scala.collection.TraversableOnce$class.toBuffer(TraversableOnce.scala:250)
at scala.collection.Iterator$$anon$19.toBuffer(Iterator.scala:399)
at scala.collection.TraversableOnce$class.toArray(TraversableOnce.scala:237)
at scala.collection.Iterator$$anon$19.toArray(Iterator.scala:399)
at com.excilys.ebi.gatling.jdbc.feeder.database.JdbcFeederSource$$anonfun$apply$1.apply(JdbcFeederSource.scala:35)
at com.excilys.ebi.gatling.jdbc.feeder.database.JdbcFeederSource$$anonfun$apply$1.apply(JdbcFeederSource.scala:28)
at com.excilys.ebi.gatling.core.util.IOHelper$.use(IOHelper.scala:22)
at com.excilys.ebi.gatling.jdbc.feeder.database.JdbcFeederSource$.apply(JdbcFeederSource.scala:28)
at com.excilys.ebi.gatling.jdbc.Predef$.jdbcFeeder(Predef.scala:21)
at com.sierrawireless.airvantage.performance.simulation.nonregression.preload.TestSimulation.(TestSimulation.scala:25)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at com.excilys.ebi.gatling.core.runner.Runner.run(Runner.scala:43)
at com.excilys.ebi.gatling.app.Gatling$$anonfun$15.apply(Gatling.scala:102)
at com.excilys.ebi.gatling.app.Gatling$$anonfun$15.apply(Gatling.scala:94)
at scala.Option.getOrElse(Option.scala:108)
at com.excilys.ebi.gatling.app.Gatling.start(Gatling.scala:94)
at com.excilys.ebi.gatling.app.Gatling$.fromMap(Gatling.scala:54)
at GatlingApplication$delayedInit$body.apply(GatlingApplication.scala:15)
at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:60)
at scala.App$$anonfun$main$1.apply(App.scala:60)
at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
at scala.collection.immutable.List.foreach(List.scala:76)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:30)
at scala.App$class.main(App.scala:60)
at GatlingApplication$.main(GatlingApplication.scala:7)
at GatlingApplication.main(GatlingApplication.scala)

Do you know anything about this issue ? Am I doing something wrong ?

Thanks for your support.

Mmmm, tricky… “Fixing” the NPE is one thing, but could you explain your use case, please?

Assuming you manage to feed those null values, how do you intend to deal with them then?

Sure I can.

I have various occurences in my table, and need them all as input of my simulation, as I need to use them all.
In this table, I have objects of the same type but some of them have null values in some columns.
Depending on filled fields, I use one column or another to perform my actions.

I used to export data from my database in a csv file and use csv feeder for that, but wanting to reduce the number of manual steps, it would be nice to connect directly to the database.
I thought about having one jdbcFeeder per kind of object, so that I don’t have any null value anymore, but I need to use all the feeders once in my simulation. And if I get right, once a feeder is empty, the whole simulation fails, so that the other feeders will not be empty at the end of my simulation.

So how did you deal with those null values when you were exporting to CSV files? Did you treat them as empty Strings? “null”?

My concern is that you might have issues with those null values downstream, after they get injected when you try to use them.

I used to put “null” as a string value.

Which is one opinionated solution amongst others. :slight_smile:

As a workaround, couldn’t you do the same thing in the SQL query with a case?

In Gatling 2, we don’t force the type to String so I think we indeed store null, which is quite dangerous. I think we should remove the key if the value is null.

Thanks for the workaround, it should do the trick.
I didn’t think about this solution, but i’ll give it a try.

Thanks again for your help.

As I said, whatever the solution, it would still be very opinionated and would suite some people and not the others.
Moreover, Gatling 2 is around the corner.