• 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
973 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 (283,440 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 (283,440 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 (283,440 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ź 2,035 wizyt
pytanie zadane 11 czerwca 2019 w Java przez JuniorPL Użytkownik (770 p.)
0 głosów
0 odpowiedzi 320 wizyt
0 głosów
2 odpowiedzi 2,385 wizyt

93,754 zapytań

142,715 odpowiedzi

323,363 komentarzy

63,350 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

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...