I’m trying to create a many-to-one base, but when adding via .jsp gives an error, via H2 console everything adds ok!
Please help me understand how to properly create a many-to-one relationship. It seems I got it wrong somewhere, or the problem is in the .jsp itself. Because as I said via the H2 console everything works well!
Thank you in advance!
My Group:
JavaScript
x
@Entity
@Table(name = "PARTY")
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@Column(name = "Name", nullable = false)
private String name;
@OneToMany(targetEntity = Team.class, mappedBy = "group", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Team> teams = new ArrayList<>();
public Group() {
}
My group controller:
JavaScript
@Controller
@RequestMapping(value = "group")
public class GroupController {
private final GroupService groupService;
@Autowired
public GroupController(GroupService groupService) {
this.groupService = groupService;
}
@GetMapping(value = "/group-list")
public String findAllGroup(Model model) {
model.addAttribute("partys", groupService.findAll());
return "groupList";
}
@GetMapping(value = "/delete")
public String deleteGroup(@RequestParam("id") Long id) {
groupService.deleteById(id);
return "redirect:/group/group-list";
}
@GetMapping(value = "/showform")
public String showFormForSave(Model model) {
Group group = new Group();
model.addAttribute("group", group);
return "groupForm";
}
@PostMapping(value = "/saveGroup")
public String saveGroup(@ModelAttribute("group") Group group) {
groupService.saveGroup(group);
return "redirect:/group/group-list";
}
}
My Team:
JavaScript
@Entity
@Table(name = "TEAM")
public class Team {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "win")
private Integer win;
@Column(name = "draws")
private Integer draws;
@Column(name = "loss")
private Integer loss;
@Column(name = "goal")
private Integer goal;
@Column(name = "miss")
private Integer miss;
@Column(name = "point")
private Integer point;
@ManyToOne
@JoinColumn(name = "group_id", referencedColumnName = "id", insertable = false, updatable = false)
private Group group;
public Team() {
}
My TeamController:
JavaScript
@Controller
@RequestMapping(value = "team")
public class TeamController {
private final TeamService teamService;
@Autowired
public TeamController(TeamService teamService) {
this.teamService = teamService;
}
@GetMapping(value = "/team-list")
public String findAllTeam(Model model) {
model.addAttribute("teams", teamService.findAll());
return "teamList";
}
@GetMapping(value = "/delete")
public String deleteTeam(@RequestParam("id") Long id) {
teamService.deleteById(id);
return "redirect:/team/team-list";
}
@GetMapping(value = "/showform")
public String showFormForSave(Model model) {
Team team = new Team();
model.addAttribute("team", team);
return "teamForm";
}
@PostMapping(value = "/saveTeam")
public String saveTeam(@ModelAttribute("team") Team team) {
teamService.saveTeam(team);
return "redirect:/team/team-list";
}
}
My .jsp form:
JavaScript
<html>
<head>
<title>Team form</title>
</head>
<body>
<form:form method="post" action="/team/saveTeam" modelAttribute="team">
<form:hidden path="id"/>
<div>
<label>Name</label>
<form:input path="name" id="name"/>
</div>
<div>
<label>Win</label>
<form:input path="win" id="win"/>
</div>
<div>
<label>Draws</label>
<form:input path="draws" id="draws"/>
</div>
<div>
<label>Loss</label>
<form:input path="loss" id="loss"/>
</div>
<div>
<label>Goal</label>
<form:input path="goal" id="goal"/>
</div>
<div>
<label>Miss</label>
<form:input path="miss" id="miss"/>
</div>
<div>
<label>Point</label>
<form:input path="point" id="point"/>
</div>
<div>
<label>Group</label>
<form:input path="group" id="group"/>
</div>
<form:button>Submit</form:button>
<button onclick="window.history.back()" type="button">Cancel</button>
</form:form>
</body>
</html>
Exception:
JavaScript
2020-07-19 21:57:42.705 WARN 9228 --- [nio-8080-exec-9] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'team' on field 'group': rejected value [1]; codes [typeMismatch.team.group,typeMismatch.group,typeMismatch.org.example.championshipFootball.model.Group,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [team.group,group]; arguments []; default message [group]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'org.example.championshipFootball.model.Group' for property 'group'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.example.championshipFootball.model.Group' for property 'group': no matching editors or conversion strategy found]]
Advertisement
Answer
You should make it a bidirectional relation, should add a @OneToMany
annotation to your Group entity, like so:
JavaScript
@OneToMany(fetch=FetchType.LAZY, mappedBy="group")
private Team team;
then, if you type just Group’s id in your jsp input, you have to create a Converter (id->Group), i.e.:
JavaScript
@Component
public class GroupIdToGroupConverter implements Converter<Integer, Group> {
@Override
public Group convert(Integer source) {
return groupRepository.findById(source); //or any other way you get your entities (entity manager, etc...)
}
}