0

I have such model for saving:

@Table("EXPERIMENTS")
data class Experiment(
    @Id val id: Long,
    val userId: Long,
    val time: String,
    @JsonProperty
    val data: Any
)

such saving processor:

@PostMapping("/experiment")
fun saveUserExperiment(@RequestBody experiment: Experiment) = service.saveExperiment(experiment)

such service:

@Service
class ExperimentService(val db: ExperimentRepository) {
    fun saveExperiment(experiment: Experiment) = db.save(experiment)
...
}

and I save it via postman in such way:

POST /experiment HTTP/1.1
Content-Type: application/json
User-Agent: PostmanRuntime/7.29.2
Accept: */*
Postman-Token: 1c2aaf40-8933-4988-b92a-6694539c3aba
Host: localhost:8080
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 105
 
{
"userId":1,
"time": "2018-10-18 05:30:57.907",
"data": {"red":123,"blue":123,"green":123}
}
 
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Date: Sat, 30 Jul 2022 15:57:55 GMT
Keep-Alive: timeout=60
Connection: keep-alive
 
{"id":7,"userId":1,"time":"2018-10-18 05:30:57.907","data":{"red":123,"blue":123,"green":123}}

during saving I receive such error:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.util.ReflectionUtils (file:/Users/_t/.gradle/caches/modules-2/files-2.1/org.springframework/spring-core/5.3.2/152489ed8223a6ad19065a3cd1ee6b9e20c0b82f/spring-core-5.3.2.jar) to field java.util.LinkedHashMap.head
WARNING: Please consider reporting this to the maintainers of org.springframework.util.ReflectionUtils
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

and also after fetching the list of models I receive such error:

Parameter specified as non-null is null: method com.example.demo.models.Experiment.<init>, parameter data

list I receive in such way:

@Query("select * from experiments")
fun getExperiments(): List<Experiment>

my database has such table:

experiments: table
    + columns
        id: int NN auto_increment = 1
        user_id: mediumtext NN
        time: timestamp default CURRENT_TIMESTAMP
        data: json
    + keys
        #1: PK (id) (underlying index PRIMARY)

I'm not sure whether it is ok that I receive 200OK response from the api but json field is null even if I have it filled.

Andrew
  • 1,947
  • 2
  • 23
  • 61
  • I doubt answer is here : https://stackoverflow.com/questions/46671472/illegal-reflective-access-by-org-springframework-cglib-core-reflectutils1 – Steephen Jul 30 '22 at 18:15
  • I got it, but hot not to disable warning, but save some data and then retrieve it? I saw similar answers, but all they are for hiding warning)) – Andrew Jul 30 '22 at 18:17

1 Answers1

1

There are two different things going on here. First, the minor one:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.util.ReflectionUtils (file:/Users/_t/.gradle/caches/modules-2/files-2.1/org.springframework/spring-core/5.3.2/152489ed8223a6ad19065a3cd1ee6b9e20c0b82f/spring-core-5.3.2.jar) to field java.util.LinkedHashMap.head
WARNING: Please consider reporting this to the maintainers of org.springframework.util.ReflectionUtils
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

As the prefix shows, this is a warning, not an error: it's not stopping your program from working (though, as it says, a later Java release might).

They cause is an incompatibility between the version of Spring you're using and the Java Module System that was introduced in Java 9, and is discussed in this question. One simple workaround might be to run it on Java 8.


The actual error is this one:

Parameter specified as non-null is null: method com.example.demo.models.Experiment.<init>, parameter data

That's about nullability. As you probably know, Kotlin distinguishes between references that could be null, and those that can't.

You've defined your JSON property as: val data: Any, and the Any type is non-nullable: Kotlin won't allow it to hold a null value. (To allow a null, you'd specify it as Any?, with a question mark.)

However, the Spring framework is based on Java, which doesn't make that distinction: all its references can potentially be null. And so there are some unfortunate corner cases which throw up unexpected nulls like this.

For some reason, your DB query is returning a null value for that field; when it tries to construct an instance of your Experiment class to hold the returned data, the Kotlin runtime spots the null and gives the error above. (It's not spotted at compile-time, unfortunately, because Spring works much of its magic at run-time.)

So there are two potential approaches to fixing it:

  • Prevent Spring returning null for that field. I don't think it's possible to guarantee this in all circumstances, as it might depend on what data can be in your database, as well as how the query is performed. (It's probably worth looking at your data and the query to understand why it's coming back as null, though.)
  • Specify the field as nullable (Any?), and handle the null case yourself. That would make your code very slightly less clean, but a lot safer and more robust.
gidds
  • 16,558
  • 2
  • 19
  • 26
  • Thank you for your help, but as you can see I don’t try to save null, my entry has all fields and also json field with some data. But after its fetching I receive null instead of data in the post request( – Andrew Jul 31 '22 at 03:44
  • @Andrew As I said: “your DB query is returning a null value for that field;” and “It's probably worth looking at your data and the query to understand why it's coming back as null”. – gidds Jul 31 '22 at 11:44