Hibernation error many to one. How to create it correctly?

Tags: , , , ,



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:

@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:

@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:

@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:

@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:

    <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:

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]]

Answer

You should make it a bidirectional relation, should add a @OneToMany annotation to your Group entity, like so:

@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.:

@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...)
    }
}


Source: stackoverflow