I have problem with JPA provided by Hibernate. Here are my entities:
@Entity
public class Action {
@Id
@GeneratedValue
private Integer id;
@Column
private String name;
@JoinColumn
@ManyToOne
private User user;
public Integer getId() { return this.id; }
protected void setId(Integer id) { this.id = id; }
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
public void getUser() { return this.user; }
protected void setUser(User user) { this.user = user; }
}
@Entity
public class User {
@Id
@GeneratedValue
private Integer id;
@Column
private String name;
@OneTomany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Action> actions = new ArrayList<>();
public Integer getId() { return this.id; }
protected void setId(Integer id) { this.id = id; }
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
public void addAction(Action action) {
action.setUser(this);
actions.add(action);
}
public void removeAction(Action action) {
actions.remove(action);
action.setUser(null);
}
public List<Action> getActions() { return Collections.unmodifiableList(actions); }
}
Here is my controller code:
@Controller
@RequestMapping("/user/{username}")
@SessionAttributes("user")
public class ActionController {
@Autowired
private TestService service;
@ModelAttribute("user")
public User contextRegistration(@PathVariable("username") String username) {
return this.service.getByName(username);
}
@RequestMapping("")
public String userView() {
return "user";
}
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String addAction(@ModelAttribute Action action) {
return "addAction";
}
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String postAddAction(@Valid Action action, BindingResult result, User user, SessionStatus sessionStatus) {
if(result.hasErrors()) {
return "addAction";
}
user.addAction(action);
this.service.saveAction(action);
sessionStatus.setComplete();
return "redirect:/user/{username}";
}
}
When method postAddAction is executed I got the following error:
org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : pl.zaprogramowany.test.model.Action.user -> pl.zaprogramowany.test.model.User
in line where method saveAction is executed.
My code is modeled on this code https://github.com/spring-projects/spring-petclinic/blob/master/src/main/java/org/springframework/samples/petclinic/web/PetController.java#L79 but I don't know why I have this error because my code is pretty similar to this.
Can anybody help?
@Edit
I'm using spring Jpa repositories and code in service layer is very simple.
@Transactional(readyOnly = true)
public User getByName(String name) {
return this.userRepository.getByName(name);
}
@Transactional
public void saveAction(Action action) {
this.actionRepository.save(action);
}