There is a class Task which is connected as ManyToOne with a class Person . If I send the Task object with all the initialized fields in the jsp to the GET request, then after POST I get the same class, but with null in all the fields that previously contained references to Person . Below is the code for both classes and the jsp page. I tried to do the Person serializable , I tried to add the @Transient Person executor field without any dependencies. In any case, in the public String updateTask(@ModelAttribute("task") Task task) method, the public String updateTask(@ModelAttribute("task") Task task) task comes with a null client and executor .

Of course, after receiving the object, you can re-extract these fields from the database, but I would like to make everything more elegant

Task class

 @Entity @AccessType(Type.PROPERTY) @NamedQueries(value = { @NamedQuery( name=Task.GET_BY_CLIENT, query="select t from Task t "+ "where t.client = :client"), @NamedQuery( name=Task.GET, query="select t from Task t "+ "left join fetch t.client " + "where t.id = :id") }) public class Task { public static final String GET_BY_CLIENT = "Task.getByClient"; public static final String GET = "Task.get"; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column private String name = ""; @Column private String description = ""; @Column private Date creationTime; @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="client_id", referencedColumnName="id") private Person client; @Transient private Person executor; //getters, setters and other logic 

and Person class

 @Entity @AccessType(Type.PROPERTY) @NamedQueries(value = { @NamedQuery( name=Person.GET, query="select distinct p from Person p "+ "left join fetch p.tasks " + "where p.id = :id") }) public class Person implements Serializable { private static final long serialVersionUID = -1631816823945986338L; public static final String GET = "Person.get"; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column private String name = ""; @OneToMany(fetch=FetchType.LAZY, orphanRemoval=true) private List<Task> tasks = new ArrayList<>(); //getters, setters, etc 

To this case there is a TaskController controller

 @RequestMapping(value = "/addTask", method = RequestMethod.GET) public ModelAndView addTask() { ModelAndView view = new ModelAndView("task"); view.addObject("task", new Task()); return view; } @RequestMapping(value = {"/addTask", "/editTask"}, method = RequestMethod.POST) public String updateTask(@ModelAttribute("task") Task task) { taskService.save(task); return "redirect:/"; } @RequestMapping(value = "/editTask", method =RequestMethod.GET) public ModelAndView editTask(@RequestParam(value="id", defaultValue="0") Long id) { Task task = taskService.find(id); task.setExecutor(new Person()); ModelAndView view = new ModelAndView("task"); view.addObject("task", task); return view; } 

The whole thing is displayed via jsp

 <form:form commandName="task" method="POST" class="form-horizontal" role="form"> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <h3><span class="label label-default">${task.id > '0' ? "Edit ": "Add "} task</span></h3> </div> </div> <c:if test="${task.client != null}"> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="button" class="btn btn-default" onclick="document.location='editPerson?id=${task.client.id}'">${task.client.name}</button> </div> </div> </c:if> <div class="form-group"> <label for="name" class="col-sm-2 control-label">Name</label> <div class="col-sm-10"> <form:input path="name" class="form-control" id="name"/> </div> </div> <div class="form-group"> <label for="description" class="col-sm-2 control-label">Description</label> <div class="col-sm-10"> <form:textarea path="description" class="form-control" id="description" rows="10"/> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">Save</button> </div> </div> </form:form> 

    1 answer 1

    1. Change

       @ManyToOne(fetch=FetchType.LAZY) 

      on

       @ManyToOne(fetch=FetchType.EAGER) 
    2. Call task.getPerson()

    3. Or set up a hibernate session, so that she would not die before rendering JSP.

    Judging by the indicated symptoms, the situation is as follows: you get a class Task but the private Person client property remains unfilled, because billed @ManyToOne(fetch=FetchType.LAZY) , which means the data will be pulled up on access. Next, the object is returned from the method, and the rendering time for the Hibernate session is gone. ==> Backfilling of the empty fields is no longer possible.