• 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

Aruba Cloud - Virtual Private Server VPS
+1 głos
751 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 (280,450 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 (280,450 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 (280,450 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,676 wizyt
pytanie zadane 11 czerwca 2019 w Java przez JuniorPL Użytkownik (770 p.)
0 głosów
0 odpowiedzi 236 wizyt
0 głosów
2 odpowiedzi 1,909 wizyt

93,324 zapytań

142,323 odpowiedzi

322,390 komentarzy

62,653 pasjonatów

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...