• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Relacja Wiele do Wielu Hibernate | zapis danych

Fiszki IT
Fiszki IT
+1 głos
36 wizyt
pytanie zadane 12 lipca w Java przez kozluck Nowicjusz (220 p.)

Witam,

mam problem z zapisywaniem danych w tabeli łączącej. Zamiast zapisywać dane w tabeli to nadpisuję się tylko pierwszy rekord w tabeli łączącej. 

Mam 2 encje: pracownika i zadania. Wyglądające tak: 

@Entity(name = "employees")
public class Employee{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "employee_id")
    private int id;

    @NotEmpty
    @NotNull
    @Size(min = 3, max = 30)
    private String name;

    @NotEmpty
    @NotNull
    @Size(min = 3, max = 30)
    private String surname;

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(
            name = "employees_tasks",
            joinColumns = @JoinColumn(name = "employee_id"),
            inverseJoinColumns = @JoinColumn(name = "task_id")
    )
    private Set<Task> tasks = new HashSet<>();

    @OneToOne
    private User user;

    public void addTask(Task task) {
        this.tasks.add(task);
        task.getEmployees().add(this);
    }  
@Entity(name = "tasks")
public class Task{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "task_id")
    private int id;
    private String title;
    private String description;
    private int numberOfLeftContractors;
    @ManyToMany(mappedBy = "tasks",cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Employee> employees = new HashSet<>();;

No i oczywiście w tych klasach poza tym kodem są settery, gettery i constructory.

Zadanie dla pracownika przydzielam w controllerze taką metodą:

@RequestMapping(value = "/task/assign/{taskId}")
    public String assignTask(@PathVariable("taskId")Integer id, @ModelAttribute Employee employee){
        Task task = tasksService.getTaskById(id);
        employee.addTask(task);
        employeeService.save(employee);
        return "redirect:/employees";
   }

 

1 odpowiedź

+1 głos
odpowiedź 12 lipca przez Wiciorny Mędrzec (165,960 p.)
wybrane 13 lipca przez kozluck
 
Najlepsza

employee.addTask(task);

 employeeService.save(employee);

Pracujesz na secie, co to jest za employee? Istnieje w bazie, jeśli nie to będzie to nowo dodany za każym razem ...  pobierasz task z serwisu po id, powinieneś tak samo pobrać employee. 
Trudno mi bez debugera odpowiedzieć.
Swoją drogą metoda dodawania nie powinna być w Encji, ponieważ każda krotka będzie miałą własne "this" to zawsze będzie nowe nadpisanie, taka metoda powinna być w serwisie i pobierać już istniejące obiekty z bazy wtedy ustawiać na nich relacje 
nie powinno być w encji 

  public void addTask(Task task) {
        this.tasks.add(task);
        task.getEmployees().add(this);
    }  

 zrobiłbym to tak w serwisie 

 Task task= taskRepository.getOne(taskId);
            Employee employee = employeeRepository.getOne(employeeId);
            employee.getTasks()
                    .add(taskId);

pisałem n aszybko więc sory za literówki, ale chcę przekazać myśl i to wywołać kidy przyjdzie encja, bo dodajesz task ... z Model attribute którego w bazie nie ma, a dla niego pobierasz liste juz relacji ten nowy model zawsze jest nowym obiektem. Jeśli istnieje powinien zostać pobrany 

komentarz 12 lipca przez Wiciorny Mędrzec (165,960 p.)
jeszcze JEDNA istotna sprawa :) korzystasz z SET - a jaki jest set? NO taki, że nie pozwala na duplikaty, jak u Ciebie wygląda w takim razie implementacja metod equals/hashCode ?
1
komentarz 13 lipca przez kozluck Nowicjusz (220 p.)
@Wiciorny, bardzo dziękuję za pomoc.

Pomogło dodanie implementacji metod hash i equals, jak i również zmiana na przekazanie employee poprzez id.
komentarz 13 lipca przez Wiciorny Mędrzec (165,960 p.)
widzisz bo domyślnie hibernate nie był wstanie rozróżnić encji, więc tutaj w dużej mierze nie wiedział nawet jak definiować ma własciciela, ciesze się zę pomogłem w razie problemów z Javą mozna pisac nawet na priv :)

Podobne pytania

0 głosów
1 odpowiedź 417 wizyt
pytanie zadane 11 czerwca 2019 w Java przez JuniorPL Użytkownik (770 p.)
0 głosów
0 odpowiedzi 36 wizyt
0 głosów
2 odpowiedzi 427 wizyt
Porady nie od parady
Zadając pytanie postaraj się o odpowiedni tytuł, kategorię oraz tagi.Tagi

84,721 zapytań

133,526 odpowiedzi

295,919 komentarzy

55,997 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...