wiered behavior of OneToMany relationship while using spring boot and spring data jpa

Logical Error :

I am developint simple Crud Application in Spring Boot with Data JPA, my goal is simple where I have two Entities: Foo.java

@Data // lombok annotation
@Entity(name = "foos")
public class Foo{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(unique = true, nullable = false)
    private Integer fooId;

    private String FooName;

    @NonNull
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "bar_id")
    private List<Bar> barList;

}

Bar.java

@Data
@Entity(name = "bars")
public class Bar{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", unique = true, nullable = false)
    private Integer barId;

    private String barTitle;

}

In my controller I want to save Foo with List of Bars as:

@Controller
@RequestMapping(value = "/foo")    
public class FooController {

    private final FooService fooService;
    private final BarService barService;

    public FooController(FooService fooService, BarService barService) {
        this.fooService = fooService;
        this.barService = barService;
    }

    @GetMapping(value = "/{id}/add_bar")
    public String addBar(@PathVariable("id") Integer id,  Model model){
        model.addAttribute("foo", fooService.findById(id));
        model.addAttribute("bar", new Bar());
        return "add_bar";
    }

    @PostMapping(value = "/{id}/add_bar")
    public String saveBar(
            @PathVariable("id") Integer id,
            @ModelAttribute("bar") Bar bar,
            BindingResult result
    ){
        if (result.hasErrors()) {
            return "add_bar";
        }
        // update foo by adding new bar and save
        Foo foo = getFooAndAddBar(id, bar);
        fooService.save(foo);
        // save bar
        barService.save(bar);

        return "redirect:/foo/" + foo.getFooId();
    }

    // update foo by adding new bar and save
    private Foo getFooAndAddBar(Integer id, Bar bar) {
        Foo foo = fooService.findById(id);
        ArrayList<Bar> barList = new ArrayList<>();
        barList.add(bar);
        foo.setBarList(barList);
        return foo;
    }
}

First bar is saved and fetched by foo id, but when ever I want to add another bar it only updates the first bar instead of inserting a new bar record in DB. is there any thing missing for @OneToMany association? or something is missing in other part of the program? please.

Silverfang :

you are setting your barlistevery time you are calling your function. You have written foo.setBarList(barList);. every time this will overwrite the previous barlist and then save it resulting in overwriting the previous values. Instead of this try this foo.getBarList().add(Bar). It will fetch the previous list of bar and then will add new bar to the list. After this just save the entity

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=19074&siteId=1