Overriding #LastModifiedDate field with provided Date in springboot mongodb auditing - spring

When performing migration of legacy data to a springboot project it is sometimes crucial, to use the same Date for auditing fields such as createdDate and lastModifiedDate.
When using mongodb auditing, it is possible to override the createdDate with a custom date using #CreatedDate annotation.
However, the same is not true for #LastModifiedDate.
Mongodb auditing always saves the document with the actual Date the document was modified on instead of overriding it with the provided date.
Using #LastModifiedDate is there a way to save LastModifiedDate with the provided date similar to when using #CreatedDate?
Thanks

Related

How does Spring-data handle/retrieve data populated by triggers and not by itself?

I have a problem with Spring Data + MySQL triggers.
Currently, before a new row is inserted in a table, a MySQL trigger assigns data to specific columns:
Table User
Columns created_at and updated_at
Those columns are mapped as follow:
#Column(name = "created_at")
private Date createdAt;
#Column(name = "updated_at")
private Date updatedAt;
Likewise, I have a service (annotated as #Transactional) which populates with data the instance User but created_at and updated_at, I mean, when I'm calling save for the userRepository those attributes go as nulls.
MySQL before to insert (trigger) into DB, both attributes are populated with the MySQL function utc_timestamp().
My problem:
Just after I call the service saveUSer, I'm calling findById from the repository. Why both attributes created_at and updated_at has null value in the instance (in db they have values)?
After saving an user , the instance will be cached inside the EntityManager. If the call of findById is still in the same transaction that is used to save the user , it will just return that user instance that is cached inside the EntityManager which the createdAt and updatedAt are null.
In JPA , we can call entityManager.refresh(user) to force selecting that user from the DB such that the user instance managed by JPA will have the latest values as the DB record. So you can use entityManager.refresh(user) after saving the user to ensure the latest value of createdAt and updatedAt are updated back to the user instance managed by JPA.
However , Spring data 's JPA repository does not expose EntityManager 's refresh, you can extend it like this.
The other answer quite accurate, however it assumes you call saveUser and findById from inside an a transaction.
However when you use Spring Data JPA under Spring Boot this issue could happen even if you are out of a transaction.
Spring Boot has a default setting which automatically encapsulates each request in a transaction.
So, if you use Spring Boot it would worth a try to add the following line to the application.properties:
spring.jpa.open-in-view=false

HibernateEnvers doesn't store current lastmodifieddate in audit table while performing delete operation

I need some help in resolving this issue. The issue is:
I am using HibernateEnvers for Auditing in spring data jpa. For insert and update operations the code is working fine. But in case of delete operation, current lastmodifieddate is not logging. The lastmodified date which is getting logged is of previous operation and not the current system date. I have set this hibernate property
org.hibernate.envers.store_data_at_delete = true
I have tried using #PostRemove and #PreRemove annotated methods to modify lastModifiedDate in entity but it doesn't work.
Please suggest some pointers on this.

Postgresql and Spring Roo Binding serial type for ID

I am having trouble using the Postgresql serial type in Spring Roo. What I want is to have the an auto-incrementing id column which will work with the auto generated entity classes in Roo.
The Postgresql sequences, which are generated with the default way of doing things in Spring Roo, work fine within the spring application. But sometimes I have to manually insert rows in the database using sql. (the sequences dont seem to work properly when I do an INSERT INTO... statement). If I could use serial type, then manual INSERTS are easy.
For example I have an office entity and and employee entity. There is a many-to-one relationship between employees and offices.
Here is my class for the Office entity.
#RooJavaBean
#RooToString
#RooJpaActiveRecord
public class Office {
#Id
#Column(name="officeid", columnDefinition = "serial")
#Generated(GenerationTime.INSERT)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long officeid;
/**
* Office Name
*/
#NotNull
#Size(max = 100)
private String name;
}
While this does work when my test inserts an office record, it fails when an employee record is inserted since the officeid foreign key value is null. (I guess it needs to flush between the office insert and the employee insert, but the auto-generate tests dont seem to do that.)
So what is the proper annotations to use to tell Roo (and hibernate/jpa) to use the serial data type, and also to work properly with inserts and relationships within the spring application?
Roo generates default JPA annotations, you must customize and setup them as needed. Note Roo guarantees your changes won't be modified.

self referencing object in JPA

I am trying to save a SystemUser entity in JPA. I also want to save certain things like who created the SystemUser and who last modified the system User as well.
#ManyToOne(targetEntity = SystemUser.class)
#JoinColumn
private SystemUser userWhoCreated;
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(iso=ISO.DATE_TIME)
private Date timeCreated;
#ManyToOne(targetEntity = SystemUser.class)
#JoinColumn
private SystemUser userWhoLastModified;
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(iso=ISO.DATE_TIME)
private Date timeLastModified;
I also want to ensure that these values are not null when persisted. So If I use the NotNull JPA annotation, that is easily solved (along with reference to another entity)
The problem description is simple, I cannot save rootuser without having rootuser in the system if I am to use a DataLoader class to persist JPA entity. Every other later user can be easily persisted with userWhoModified as the "systemuser" , but systemuser it's self cannot be added in this scheme.
Is there a way so persist this first system user (I am thinking with SQL). This is a typical bootstrap (chicken or the egg) problem i suppose.
Have you tried rootUser.setUserWhoLastModified(rootUser) ?

Hibernate Timestamp with Timezone

I'm new to Hibernate and am working with an Oracle 10g database. We have columns in our tables that are of type TIMESTAMP WITH TIMEZONE. Hibernate does not seem to support this mapping directly. Is there a standard way to go about this?
An example of a UserType storing java.util.Calendar with time zone information is given in this blog post: http://www.joobik.com/2010/12/mapping-dates-and-time-zones-with.html
TIMESTAMP WITH TIMEZONE is Oracle extension and thus is not supported by Hibernate out of the box. You have two options:
1) Change your table structure to store timezone in a separate column (as VARCHAR2). Hibernate is able to map java.util.TimeZone as timezone type using its ID.
2) Write a custom class to hold both timestamp and timezone and a custom UserType that would persist it. It will have to be a CompositeUserType if you need the ability to use its individual properties (e.g. timezone or timestamp) in queries. Look at this example to get you started; you'll need to alter it to actually store the timezone.

Resources