Many to Many Java Spring

У меня есть 2 сущности, соединенные многими со многими. Шаблон должен содержать список:

владелец1

приют 1 приют 2

владелец1 приют 1

Но я не понимаю, как я могу ссылаться на таблицу ссылок, нужен ли мне третий владелец-укрытие Нужно ли создавать хранилище для таблицы соединений?

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@DynamicUpdate
@Entity
@Table(name = "owner")
public class Owner {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int idOwner;

    private String name;

    private String address;

    private String description;

    @ManyToMany(cascade = {CascadeType.ALL})
    @JoinTable(
            name = "owner_shelter",
            joinColumns = {@JoinColumn(name = "owner")},
            inverseJoinColumns = {@JoinColumn(name = "shelter")}
    )
    private Set<Shelter> shelterOwner;
}

-

@Data
@DynamicUpdate
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    @Entity
    @Table(name = "shelter")
    public class Shelter {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;

        private String name;
        private String address;
        private String description;

    @ManyToMany(mappedBy = "shelterOwner")
    private Set<Owner> sheltersOwner;
    }

пока что я могу вывести только список

    @Autowired
    ShelterRepository shelterRepository;
    @Autowired
    OwnerRepository ownerRepository;

    @GetMapping("/shelters")
    public String getPage(Authentication authentication, Model model) {
        if (authentication != null) {
            model.addAttribute("authentication", authentication);
        }
        List<Shelter> shelters = shelterRepository.findAll();
        List<Owner> owners = ownerRepository.findAll();
        model.addAttribute("shelters", shelters);
        model.addAttribute("owners", owners);
        return "shelterList";

    }
}

введите сюда описание изображения


Ответы (1 шт):

Автор решения: Antonio112009

Объяснение:

  1. На Lombok лучше на 100% не полагаться. читать тут Item 45. и это
  2. Я заменил дублирующийся shelterOwner, потому что это не shelterOwner, а owners (это же список) и shelters (это же список).
  3. Изменил в Id IDNETITY на кастомный. Про способы генерации читать тут и мой вопрос на ruSO - тут
  4. Зачем нужны методы AddOwner, RemoveOwner, AddShelter, RemoveShelter? так как у вас (как я понял) зависимость в две стороны (bidirectional), то надо как делать рекурсию объектов, то есть объект А должен ссылаться на Б, а Б на А, А на Б и так вечно. Если просто добавить A к Б (без обратной зависимости), то у вас может и не получиться двухнаправленная зависимость. Именно таким способом мы связываем объекты между собою.
  5. Избавиться от ненужных аннотаций. Прочитайте для чего какая аннотация нужна.
  6. Про model.addAttribute("authentication", authentication);. Это лишняя строчка. Если вы хотите взять email, то вот вариант: <span th:text="${#authentication.getPrincipal().getUsername()}"></span> (для Thymeleaf). Если вам нужно отобразить данные в зависимости от уровня достпа юзера - https://www.thymeleaf.org/doc/articles/springsecurity.html

Owner.java

@Data
@AllArgsConstructor
@NoArgsConstructor
@DynamicUpdate
@Entity
@Table
public class Owner {
    @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "owner_generator")
  @SequenceGenerator(name="owner_generator", sequenceName = "owner_seq", allocationSize = 1, initialValue = 1)
    private Long id;

    private String name;

    private String address;

    private String description;

    @ManyToMany(fetch = FetchType.LAZY,
            cascade = CascadeType.ALL
    )
    @JoinTable(name = "owner_shelter",
            joinColumns = { @JoinColumn(name = "owner_id") },
            inverseJoinColumns = { @JoinColumn(name = "shelter_id") })
    private List<Shelter> shelters = new ArrayList<>();

    public void addShelter(Shelter shelter) {
      shelters.add(shelter);
      shelter.getOwners().add(this);
    }

    public void removeShelter(Shelter shelter) {
      shelters.remove(shelter);
      shelter.getOwners().remove(this);
    }
}

Shelter.java

@Data
@DynamicUpdate
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table
public class Shelter {

  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "shelter_generator")
  @SequenceGenerator(name="shelter_generator", sequenceName = "shelter_seq", allocationSize = 1, initialValue = 1)
    private Long id;

  private String name;
  private String address;
  private String description;

   @ManyToMany(mappedBy = "shelters")
   private List<Owner> owners;

   public void addOwner(Owner owner) {
      owners.add(owner);
      owner.getShelters().add(this);
   }

   public void removeOwner(Owner owner) {
      owners.remove(owner);
      owner.getShelters().remove(this);
   }

  }
}

Пример добавления приютов к владельцу


    @Autowired
    ShelterRepository shelterRepository;

    @Autowired
    OwnerRepository ownerRepository;

    public void addNewShelters (){
      Shelter shelter1 = new Shelter();
      shelter1.setName("приют1");
      Shelter shelter2 = new Shelter();
      shelter2.setName("приют2");
      shelterRepository.save(shelter1);
      shelterRepository.save(shelter2);

      Owner owner = new Owner();
      owner.setName("владелец");
      owner.addShelter(shelterRepository.findByName("приют1"));
      owner.addShelter(shelterRepository.findByName("приют2"));
      ownerRepository.save(Owner);

      Owner ownerDB = ownerRepository.getByName("владелец");
      System.out.println("Приюты: \n" + ownerDB.get(0).getName);
      System.out.println(ownerDB.get(1).getName);

      //Другой код
      for (Owner ownerItem : ownerRepository.findAll()){
        System.out.println("Владелец:" + ownerItem.getName());
        System.out.println("Приюты:");

        for (Shelter shelterItem : shelterRepository.findAll()){
          System.out.println("Название: " + shelterItem.getName());
        }

      }


    }
→ Ссылка