Issue
I am trying to update an entity by modifying the user defined member variable using the repository.save() method. The object is correctly updated and persisted but the timestamp of the member variable in the entity with the annotation @UpdateTimestamp is not getting updated.
My Entity classes are CASH & RATE:
@Entity
@Table(name = "CASH")
public class Cash{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "cash_id")
private List<Rate> rates = new ArrayList<>();
@ManyToOne(fetch = FetchType.EAGER)
private User createdBy;
@CreationTimestamp
@Column(name = "CREATED", nullable = false)
private ZonedDateTime created;
@Column(name = "LAST_MODIFIED", nullable = false)
@UpdateTimestamp
private ZonedDateTime lastModified;
@Entity
@Table(name = "RATE")
public class Rate {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@Column(name = "PRODUCT")
private String product;
@Column(name = "PRICE")
private String product;
Repositories for both the CASH and RATE class :
@Repository
public interface CashRepository extends JpaRepository<Cash, Long> {
Optional<Cash> findTopOrderByCreatedDesc();
}
@Repository
public interface RateRepository extends JpaRepository<Rate, Long> {
}
The update() method written in the service of Cash looks like :-
public void updateRate(Long productId, RateDto rateDto, Authentication authentication) {
User user = userService.getCurrentUser(authentication);
Optional<Cash> cashRate = cashRepository.findTopOrderByCreatedDesc();
if (Cash.isPresent()) {
Cash latestCash = cashRate.get();
List<Rate> rateList = latestCash.getRates();
for(Rate rate: rateList){
if(Objects.equals(rate.getId(), productId))){
rate.setProduct("Update Product");
}
}
rate newRates = mapToRates(rateDto, user); // the rateDto will have all the fields different(updated fields)
rateList.add(newRates);
latestCash.setRates(rateList);
Cash updatedCashAlternative = cashAlternativeProductsRepository.save(latestCash);
} else{
throw new CashException();
}
}
The latestCash object is perfectly getting saved with the updated list of rates but the lastModified field in the object is not getting updated. Is @UpdateTimestamp only works if any of the non composite member variable is changed/updated. ??
Also i tried extending the CrudRepository instead of JpaRepository and tried updating it using the repository.update() method but it didn't work.
Solution
Changing the contents of an associated object (Rate
) or the join table (cash_rates
?) does not make the referring object Cash
"dirty". I think if you switch to an @ElementCollection
and make the Rate
an @Embeddable
, any change to these objects will make the object Cash
be considered as "dirty" and hence the lastModified
attribute will be updated.
If that doesn't work, you'll have to update the timestamp yourself in the code.
Answered By - Christian Beikov
Answer Checked By - Dawn Plyler (JavaFixing Volunteer)