• 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

+1 głos
899 wizyt
pytanie zadane 12 lipca 2021 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 2021 przez Wiciorny Ekspert (282,580 p.)
wybrane 13 lipca 2021 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 2021 przez Wiciorny Ekspert (282,580 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 2021 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 2021 przez Wiciorny Ekspert (282,580 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ź 1,895 wizyt
pytanie zadane 11 czerwca 2019 w Java przez JuniorPL Użytkownik (770 p.)
0 głosów
0 odpowiedzi 293 wizyt
0 głosów
2 odpowiedzi 2,199 wizyt

93,630 zapytań

142,551 odpowiedzi

323,054 komentarzy

63,134 pasjonatów

Advent of Code 2025

Top 15 użytkowników

  1. 2174p. - dia-Chann
  2. 2153p. - DziarnowskiJ
  3. 2123p. - Łukasz Piwowar
  4. 2077p. - raydeal
  5. 1989p. - CC PL
  6. 1957p. - Maurycy W
  7. 1954p. - Adrian Wieprzkowicz
  8. 1895p. - rucin93
  9. 1855p. - Michal Drewniak
  10. 1777p. - robwarsz
  11. 1701p. - rafalszastok
  12. 1588p. - Tomasz Bielak
  13. 1564p. - Łukasz Eckert
  14. 1491p. - Rafał Trójniak
  15. 1377p. - ssynowiec
Szczegóły i pełne wyniki

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Kursy INF.02 i INF.03
...