spring mvc +hibernate one to many delete option - spring

i am working on spring mvc but i am facing this problem
Provided id of the wrong type. Expected: class java.lang.Long, got class java.lang.Integer
here is my dao code
#Override
public String delete(long id) {
/*sessionFactory.getCurrentSession().createQuery("DELETE FROM Invoice WHERE id = "+ id).executeUpdate();*/
sessionFactory.getCurrentSession().createQuery("DELETE FROM InvoiceBatch WHERE id = "+ id).executeUpdate();
return "Successfuly Deleted";
}
here is my contoller
#RequestMapping(value="/delete",method=RequestMethod.GET)
public ModelAndView deleteEmployee( #RequestParam("id") String id, ModelMap model)
{
Long eid =Long.parseLong(id);
model.put("message",invoicManager.delete(eid));
//model.put("", invoicManager.clientList());
return new ModelAndView("Invoices", model);
}
here is my pojo
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name="BATCH_REFERE
am i missing something
kindly help

Related

Spring MVC and Hibernate

I'm using hibernate to store a Student object which is having an embedded type Address object. I'm using a form to get inputs name, city, state. City & State getting null while submitting the form how to capture these values in Model Object. ${student.homeAddress.city} - This value is NULL
Issue Resolved!
public class Student {
#Id
#Column(name = "student_id")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "students_seq")
#SequenceGenerator(sequenceName = "students_seq", name = "students_seq", allocationSize = 1)
private int studentId;
#Column(name = "student_name")
private String studentName;
#Embedded
private Address homeAddress;
}
#Controller
#RequestMapping("/students")
public class StudentController {
#Autowired
StudentService studentService;
#RequestMapping("/registrationForm")
public String showFormForStudentRegistration(Model model) {
Student studentObj = new Student();
Address addressObj = new Address();
studentObj.setHomeAddress(addressObj);
model.addAttribute("student", studentObj);
return "student-form";
}
#RequestMapping("/register")
public String registerStudent(#ModelAttribute("student") Student student) {
studentService.createStudent(student);
return "student-success";
}
}
**${student.address.state} -> This is how needs to be accessed after submitting it. when submitting form it should be like this <form:input path="address.state" **
Data successfully inserted.

Spring Data Audit, CreatedBy lost on Update [duplicate]

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.
Use updatable attribute of #Column annotation like below.
#Column(name = "created_date", updatable = false)
private Date createdDate;
This will retain the created date on update operation.
Your method in your (#)Controller class is not that efficient. You don't want to (manually) retrieve the object and copy all the fields, relationships etc. over to it. Next to that with complex objects you will sooner or alter run into big trouble.
What you want is on your first method (the GET for showing the form) retrieve the user and store it in the session using #SessionAttributes. Next you want an #InitBinder annotated method to set your validator on the WebDataBinder so that spring will do the validation. This will leave your updateFromForm method nice and clean.
#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";
}
}
You will need to add the SessionStatus attribute to the method and mark the processing complete, so that Spring can cleanup your model from the session.
This way you don't have to copy around objects, etc. and Spring will do all the heave lifting and all your fields/relations will be properly set.
In my case #CreatedDate and #CreatedBy fields were not removed from databse during update, but were not queried by #Repository findOne method.
Changing
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
into
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
on #Entity class helped with that.

Spring - How to use #RequestParam parameter of a Controller in a Custom Validator class?

I've got a problem about validation in Spring MVC with Hibernate.
I want a validator that valid user input, but the validation must be done out of the controller, so, in a separate validation class.
The situation: this is the head of my controller in which I want to do the validation. I need that id to retrieve a list of Booking of a specific car.
#PostMapping(value = "/rent")
public ModelAndView vehicleRent(#ModelAttribute("newBooking") Booking booking, BindingResult bindingResult, #RequestParam("id") long id) {
But if i want to separate the logic out of this controller creating a custom validator, i have this result:
public class BookingValidator implements Validator {
#Autowired
VehicleBO vehicleBo;
#Override
public boolean supports(Class<?> type) {
return Booking.class.isAssignableFrom(type);
}
#Override
public void validate(Object o, Errors errors) {
Booking booking = (Booking) o;
//other code
rejectIfBookingExists(booking, 0, errors, "validation.booking.startdate.exists");
}
}
public boolean rejectIfBookingExists(Booking booking, long id, Errors errors, String key){
boolean exists = false;
List<Booking> vehicleBookings = vehicleBo.getVehicleBookings(id);
if (booking != null || booking.getStartDate() != null || booking.getFinishDate() != null) {
for (Booking b : vehicleBookings) {
if (booking.getStartDate().before((b.getFinishDate())) || booking.getStartDate().equals(b.getFinishDate())) {
errors.rejectValue("startDate", key);
exists = true;
break;
}
}
}
return exists;
}
}
In this way I cannot retrieve the list because i don't have the required id, could you explain me how to do that? Or,there are other ways to solve this problem?
Thanks!
EDIT:
This is the Booking class, as you can see it has a Vehicle object mapped inside
#Entity
public class Booking implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#ManyToOne
#JoinTable(name="user_booking", joinColumns={#JoinColumn(name ="booking_id", referencedColumnName ="id")},
inverseJoinColumns={#JoinColumn(name ="user_id", referencedColumnName ="id")})
private User user;
#ManyToOne
#JoinColumn(name = "vehicle_id")
private Vehicle vehicle;
#DateTimeFormat(pattern = "dd/MM/yyyy")
private Date startDate;
#DateTimeFormat(pattern = "dd/MM/yyyy")
private Date finishDate;
public Booking() {
//getter and setter and other code
}
Any ideas?
Why don't you simply map the vehicle id as booking.vehicle.id in your form? Provided Vehicle has a no-arg constructor (which it probably does, being an entity), the Booking should come back in the POST request handler with an instantiated Vehicle, along with its id property set. You should then be able to access booking.vehicle.id from wihtin the validator.
You can use an input[type=hidden] for the booking.vehicle.id field. In your GET request for the view with the form, simply inject the vehicle id as a #PathVariable and copy it to your model, so that you could reference the value inside the form.

Spring, modelmap, getting attributes for displaying Lists in JSTL <c:foreach>

I, a newbie in progrmming, develop spring MVC application with spring mvc frameworks. I want to list the data into table by using JSTL with 2 mapped entities.
<c:forEach items="${empList}" var="emp">
<tr class="odd gradeX">
<td>${emp.icode}</td>
<td>${emp.employeeName}</td>
//problem here
//I want to get employee's phone num
<td>${emp.ph_number}</td>
</tr>
</c:forEach>
This is the example of my Entity,
1) Employee Entity
#Entity
public class Employee implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long employeeId;
private String employeeName;
#OneToMany(mappedBy="employee" ,cascade={CascadeType.ALL})
private List<Phone>phones;
//method getter setter }
2)Phone Entity
#Entity
public class Phone implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long phoneId;
private String ph_number;
#ManyToOne
private Employee employee;
//method getter setter}
3)Enployee Controller
#Controller
public class EmployeeController {
#EJB(mappedName = "ejb:/EJB//EmployeeServiceBean!com.mfu.ejb.EmployeeService")
EmployeeService empServ;
#RequestMapping("/listEmp")
public ModelAndView listEmployee(HttpServletRequest request) {
ModelAndView mv = new ModelAndView("ListEmp.jsp");
List<Employee> empList;
try {
empList = empServ.getAllEmployee();
mv.addObject("empList", empList);
} catch (Exception e) {
e.printStackTrace();
}
return mv;
}
}
Thankyou and sorry for my bad English. Hope it make sence.

Spring MVC with Hibernate Validator Mandatory for the database field, but not in the application

Problem with BindingResult hasErrors() in validation.
I have this code:
#RequestMapping(value = "/entity", params = "form", method = RequestMethod.POST)
public String submit(#Valid #ModelAttribute Entity entity, BindingResult result) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
entity.setCreatedBy(auth.getName());
if (result.hasErrors()) {
//Here the error of createdBy is null
return "entity/new";
} else {
entityService.save(entity);
return "redirect:/entity/list";
}
}
the entity class:
#Entity
#Table(name = "TABLE_X")
public class Entity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#NotNull
#Column(name = "primary_key")
private String primaryKey;
#NotNull
#Column(name = "created_by")
private String createdBy;
//getters and setter
}
I need set the value of createdBy in controller but always show "may not be null" in view.
Please help.
Spring MVC 4, Hibernate Validator 5, Database Oracle 11g
You entity object is validated before Spring MVC invokes the submit() method. The result object is created at the same time. This line:
entity.setCreatedBy(auth.getName());
has absolutely no effect on the outcome of result.hasErrors().

Resources