Spring JPA审计为空createdBy
我正在使用Spring Data的审核功能,并且有一个类似如下的类:
@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;
...
现在,我相信我已经配置好审计,因为我可以看到createdBy,createdDate,lastModifiedBy和lastModifiedDate都在我更新域对象时获得了正确的值。
但是,我的问题是,当我更新一个对象时,我失去了createdBy和createdDate的值。 所以,当我第一次创建对象时,我拥有全部四个值,但是当我更新它时,createdBy和createdDate都是无效的! 我也使用Hibernate envers来保存域对象的历史记录。
你知道为什么我会得到这种行为吗? 为什么更新域对象时,createdBy和createdDate是空的?
更新:回答@ m-deinum的问题:是的弹簧数据JPA配置正确 - 其他一切正常 - 我真的不想发布配置,因为你的udnerstand需要大量的空间。
我的AuditorAwareImpl就是这样
@Component
public class AuditorAwareImpl implements AuditorAware {
Logger logger = Logger.getLogger(AuditorAwareImpl.class);
@Autowired
ProfileService profileService;
@Override
public String getCurrentAuditor() {
return profileService.getMyUsername();
}
}
最后,这是我的更新控制器实现:
@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";
}
更新2:请看看更新的版本
@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";
}
当我做更新时,这仍然留下createdBy和createdDate字段:
它也没有得到学校的价值(这不包含在我的表单中,因为它与用户正在编辑有关),所以我需要再次从SecurityContext中获得它...我做错了什么?
更新3:供参考,不要错过评论:主要问题是我需要将@SessionAttributes注释包含到我的控制器中。
您的(@)Controller类中的方法效率不高。 您不想(手动)检索该对象并将所有字段,关系等复制到该对象。 在那些复杂的物体旁边,你会更快或者更快地遇到麻烦。
你想要的是你的第一个方法(用于显示表单的GET)使用@SessionAttributes检索用户并将其存储在会话中。 接下来,您需要一个@InitBinder注释方法来在WebDataBinder上设置验证器,以便Spring将进行验证。 这会让你的updateFromForm方法updateFromForm很干净。
@Controller
@RequestMapping("/edit/{id}")
@SessionAttributes("student")
public EditStudentController
@Autowired
private StudentFormValidator validator;
@Autowired
private StudentRepository studentRep;
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setValidator(validator);
}
@RequestMapping(method=RequestMethod.GET)
public String showUpdateForm(Model model) {
model.addObject("student", studentRep.secureFind(id));
return "students/form";
}
@RequestMapping(method=RequestMethod.POST)
public String public String updateFromForm(@Valid @ModelAttribute Student student, BindingResult result, RedirectAttributes redirectAttributes, SessionStatus status) {
// Optionally you could check the ids if they are the same.
if (result.hasErrors()) {
return "students/form";
}
redirectAttributes.addFlashAttribute("message", "?p?t???? p??s????!");
studentRep.save(student);
status.setComplete(); // Will remove the student from the session
return "redirect:/students/list";
}
}
您需要将SessionStatus属性添加到方法中并标记处理完成,以便Spring可以从会话中清除模型。
这样你就不必复制物体等等,Spring将会完成所有的起重工作,你所有的领域/关系都会被正确设置。
使用@Column注释的可更新属性,如下所示。
@Column(name = "created_date", updatable = false)
private Date createdDate;
这将在更新操作中保留创建的日期。
链接地址: http://www.djcxy.com/p/48833.html