Search code examples
javaoraclespring-boothibernatejpa

Object value not saving to the database through Hibernate


I am working on a Spring Boot project that uses Hibernate to interact with an Oracle database.

The save functionality isn't working as expected. It is just the default implementation from the Spring Data JPA framework that takes in an object and saves it to the repository. The object definition has a field called frequencyQty that has these definitions:

@Column(precision=10, scale=2)
private BigDecimal frequencyQty;

...

public BigDecimal getFrequencyQty() {
    return frequencyQty;
}

public void setFrequencyQty(BigDecimal frequencyQty) {
    this.frequencyQty = frequencyQty;
}

The precision of 10 and scale of 2 exactly match the definition of the database column as well.

The problem is that Hibernate is not saving this field to the database correctly. If that field in the database is null, then nothing ever gets saved. But if the field in the database has a value in it already, then it can save other values just fine.

For example, if the field in the database is null and I try to save 4, it remains null. If the field in the database is 1 and I try to save 4, then it saves 4 like expected.

I have done everything I can think of to debug why this is happening. Other fields for this object save normally, overriding null values if they exist, even when they're saved at the same time as frequencyQty. This is an important detail, because it means the row is getting saved to the database correctly except for this one specific field. The debugger confirms that the correct values are set in frequencyQty at the time the save functionality is called. I have found absolutely nothing to suggest there should be anything special about this field.

Anyone have any ideas?

EDIT: Oracle version is 19c Standard Edition 2 Release 19.0.0.0.0

EDIT: When I check the SQL logs, it appears that the correct SQL is being called to set frequencyQty, but later some SQL is called that sets frequencyQty back to null. This definitely isn't being done manually, and now I'm just trying to figure out why this script would be running automatically.


Solution

  • I found where the problem came from. I still don't quite understand why it is a problem at all, but I at least found out what fixed it.

    Basically, the API endpoint that was called to save frequencyQty was receiving a JSON node that mapped to the object containing the frequencyQty field. In the code, I convert the JSON node into the object, set frequencyQty, and save it to the database. For some reason, after the code is finished running, there is something that automatically calls for the database to save the old value that was passed into the API endpoint through that JSON node, which held the frequencyQty as null. I still don't understand why that was happening automatically, but once I traced it back to that, I just changed the logic for what was sent to the API.

    I have spent 20+ hours trying to figure out this bug. I am still confused as to why it exists, but for now, I'm accepting the fix and moving on with my life.

    EDIT 2/2/2024:

    This problem cropped up again two months later, and I finally figured out the problem. I was calling two endpoints - one that updated and saved the object, and one that saved the object as it was. The second endpoint was running last, which meant it was overriding all the changes from the first endpoint. I feel dumb but mostly relieved to finally have an answer.