• 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

VPS Starter Arubacloud
+1 głos
489 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 (269,120 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 (269,120 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 (269,120 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,149 wizyt
pytanie zadane 11 czerwca 2019 w Java przez JuniorPL Użytkownik (770 p.)
0 głosów
0 odpowiedzi 204 wizyt
0 głosów
2 odpowiedzi 1,420 wizyt

92,452 zapytań

141,261 odpowiedzi

319,074 komentarzy

61,854 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.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...