I'm trying to create an API where I'm updating a set of data into database. While updating, there is data that comes the same as what's already present in the DB. I want to check this and avoid sending that particular data again to DB as it's of no use and it might also help on performance.
Here in the below code snippet it always goes inside the equals condition giving the logger message, even if I pass different data. I see that both optional object and updatedObj both getting updated with values making it same.
Optional<Books> optBook = abcDAO.findById(bookId);
Books updatedObj = new Books();
updatedObj = optBook.orElseThrow(() -> new RuntimeException("Book Not Found - "+bookId));
Books bookDB = optBook.get();
updatedObj = updateBookValues(updatedObj, data); //-------------> Method to set values to updatedObj from data
if (bookDB.equals(updatedObj))
logger.info("No Data change happened for books - " + bookId);
else
abcDAO.save(updatedObj);
The code snippet for updateBookValues method as below,
public Book updateBookValues(Book book, JSONObject data) {
data.keySet().forEach(field -> {
switch (field) {
case Constants.FIELD_1:
book.setField_1(data.optString(Constants.FIELD_1));
break;
case Constants.FIELD_2:
book.setField_2(data.optString(Constants.FIELD_2));
break;
case Constants.FIELD_3:
book.setField_3(data.optString(Constants.FIELD_3));
break;
default:
break;
}
});
return book;
}
Whenever I try to set the values for updatedObj, bookDB from
bookDB = optBook.get();
is also getting updated
Please let me know why or how to stop this updation.
As bmargulies mentioned, updatedObj and bookDB point to the same object. You can't update one and compare it to the other and expect to get any differences.
You don't really provide information about how the persistence layer is implemented. If you are working with jpa and attached entities, jpa will take care of changes automatically & updated the db when the transaction is committed.
if you want to/need to work with detached objects, then of course you need to execute save() manually and ideally only when needed.
There are different options, one of them might be something like:
abcDAO.findById(bookId)
.ifPresentOrElse(book -> {
if(hasChanges(book, data)){
updateBookValues(book, data)
abcDAO.save(book);
}
},
() -> new RuntimeException("Book Not Found - "+bookId));
-> Implement a method hasChanges(Book book, JSONObject data) that doesn't update the book but only checks if the book needs to be updated (or just do the check inside updateBookValues() and return the boolean as a result)