Witajcie,
Znalazłem bardzo fajny projekt na githubie i postanowiłem napisać coś na jego podstawie. Padło na prostą aplikacje gdzie można dodawać użytkowników, a do każdego użytkownika jakąś akcję. Problem w tym, że podczas pisania kodu trafiłem na błąd. Treść tego błędu jest dla mnie całkowicie zrozumiała, tak samo jak zasada działania kodu w poniższym projekcie. Problem w tym że nie mam pomysłu jak zaradzić temu błędowi i dziwię się czemu nie występuje on w wymienionym projekcie, ponieważ mój kod jest prawie identyczny.
https://github.com/spring-projects/spring-petclinic
Moje encje:
@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); }
}
Warstwa serwisowa:
@Transactional(readyOnly = true)
public User getByName(String name) {
return this.userRepository.getByName(name);
}
@Transactional
public void saveAction(Action action) {
this.actionRepository.save(action);
}
I warstwa controller:
@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);
// W poniższej linijce zostaje wyrzucony wyjątek
this.service.saveAction(action);
sessionStatus.setComplete();
return "redirect:/user/{username}";
}
}
Tutaj link do podobnej linijki w tym projekcie: https://github.com/spring-projects/spring-petclinic/blob/master/src/main/java/org/springframework/samples/petclinic/web/PetController.java#L99
No i mój bład:
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
Macie jakiś pomysł jak temu zaradzić? Wiecie co robię źlę?