I am using the auditing capabilities of Spring Data and have a class similar to this:
@Entity
@Audited
@EntityListeners(AuditingEntityListener.class)
@Table(name="Student")
public class Student {
@Id
@GeneratedValue (strategy = GenerationType.AUTO)
private Long id;
@CreatedBy
private String createdBy;
@CreatedDate
private Date createdDate;
@LastModifiedBy
private String lastModifiedBy;
@LastModifiedDate
private Date lastModifiedDate;
...
Now, I believe I have configured auditing fine because I can see that createdBy, createdDate, lastModifiedBy and lastModifiedDate all are getting the correct values when I update the domain objects.
However, my problem is that when I update an object I am losing the values of createdBy and createdDate. So, when I first create the object I have all four values, but when I update it createdBy and createdDate are nullified ! I am also using the Hibernate envers to keep a history of the domain objects.
Do you know why do I get this behavior ? Why do createdBy and createdDate are empty when I update the domain object ?
Update: To answer @m-deinum 's questions: Yes spring data JPA is configured correctly - everything else works fine - I really wouldn't like to post the configuration because as you udnerstand it will need a lot of space.
My AuditorAwareImpl is this
@Component
public class AuditorAwareImpl implements AuditorAware {
Logger logger = Logger.getLogger(AuditorAwareImpl.class);
@Autowired
ProfileService profileService;
@Override
public String getCurrentAuditor() {
return profileService.getMyUsername();
}
}
Finally, here's my update controller implementation:
@Autowired
private StudentFormValidator validator;
@Autowired
private StudentRepository studentRep;
@RequestMapping(value="/edit/{id}", method=RequestMethod.POST)
public String updateFromForm(
@PathVariable("id")Long id,
@Valid Student student, BindingResult result,
final RedirectAttributes redirectAttributes) {
Student s = studentRep.secureFind(id);
if(student == null || s == null) {
throw new ResourceNotFoundException();
}
validator.validate(student, result);
if (result.hasErrors()) {
return "students/form";
}
student.setId(id);
student.setSchool(profileService.getMySchool());
redirectAttributes.addFlashAttribute("message", "Επιτυχής προσθήκη!");
studentRep.save(student);
return "redirect:/students/list";
}
Update 2: Please take a look at a newer version
@RequestMapping(value="/edit/{id}", method=RequestMethod.GET)
public ModelAndView editForm(@PathVariable("id")Long id) {
ModelAndView mav = new ModelAndView("students/form");
Student student = studentRep.secureFind(id);
if(student == null) {
throw new ResourceNotFoundException();
}
mav.getModelMap().addAttribute(student);
mav.getModelMap().addAttribute("genders", GenderEnum.values());
mav.getModelMap().addAttribute("studentTypes", StudEnum.values());
return mav;
}
@RequestMapping(value="/edit/{id}", method=RequestMethod.POST)
public String updateFromForm(
@PathVariable("id")Long id,
@Valid @ModelAttribute Student student, BindingResult result,
final RedirectAttributes redirectAttributes, SessionStatus status) {
Student s = studentRep.secureFind(id);
if(student == null || s == null) {
throw new ResourceNotFoundException();
}
if (result.hasErrors()) {
return "students/form";
}
//student.setId(id);
student.setSchool(profileService.getMySchool());
studentRep.save(student);
redirectAttributes.addFlashAttribute("message", "Επιτυχής προσθήκη!");
status.setComplete();
return "redirect:/students/list";
}
This still leaves empty the createdBy and createdDate fields when I do an update :(
Also it does not get the School value (which is not contained in my form because it is related to the user currently editing) so I need to get it again from the SecurityContext... Have I done anything wrong ?
Update 3: For reference and to not miss it in the comments: The main problem was that I needed to include the @SessionAttributes annotation to my controller.