Issue
I am seeing a weird behavior of the LastModifiedDate functionality of spring data.
Please refer to this example code:
@Entity
class Store {
@OneToMany(cascade = REFRESH, fetch = EAGER, mappedBy="store")
List<Products> products;
@LastModifiedDate
Instant modificationDate;
}
@Entity
class Product {
@ManyToOne(cascade = REFRESH)
Store store;
@LastModifiedDate
Instant modificationDate;
double price;
boolean available;
}
@Service
class ProductsService {
void reduceMaxProductPrice(UUID storeId, double reduceBy) {
var store = storeRepository.findById(storeId);
var product = store.getProducts().max(p.getPrice()); // Pseudo - get by price
product.setPrice(product.getPrice() - reduceBy);
productRepository.save(product);
// make changes to store - and save
storeRepository.save(store);
}
}
I would assume that since I store the product first and then the store, the last modified date of the store will be after the one of the product. In practice, in most cases (95%+) this is as expected, but I do see cases where the product last modified is after the one from the store.
I am trying to understand what might cause this issue? Could you please contribute about how spring (and hibernate) handles this LastModifiedDate?
Thank you.
Solution
Spring Data and I assume Hibernate as well uses life cycle events to set these kinds of dates.
In general these are independent of the order in which you call save
because with JPA a call to save
or persist
or merge
doesn't actually write your object to the database but just registers it to be written eventually. Hibernate may and will reorder the actual database operations and with them the order in which events are raised.
Answered By - Jens Schauder
Answer Checked By - Marie Seifert (JavaFixing Admin)