Jpa ManyToMany отношения не работают - PullRequest
0 голосов
/ 23 апреля 2019

У меня есть SpringBoot 2.1.3 + база данных MySql 5.7. Я пытаюсь установить отношения ManyToMany между двумя объектами:

@Entity
@Data
public class User {
    private String name;
    @ManyToMany(cascade = CascadeType.ALL)
    private List<Hobby> hobbies;
}

@Entity
@Data
public class Hobby {
    private String description;
    @ManyToMany(mappedBy = "hobbies")
    private List<User> users;
}

Теперь, если я сделал тест:

User user = new User();
user.setName("James");
user.setHobbies(new ArrayList<>());

Hobby hobby = new Hobby();
hobby.setDescription("Golf");
hobby.setUsers(new ArrayList<>());

user.getHobbies.add(hobby);
hobby.getUsers.add(user);

userRepository.save(user);

Все три таблицы сохраняются (таблица пользователя, таблица хобби и таблица сопоставления, созданная jpa) следующим образом:

USER              USER_HOBBY               HOBBY
id, name          iduser, idhobby          id, description
1   James         1        1               1   Golf

Но если сейчас я позвоню

List<User> us = userRepository.findAll();

внутри нас У меня нет хобби-сущностей ... Он сказал:

com.sun.jdi.InvocationException occurred invoking method.

Мои application.properties с конфигом БД:

# Connection url for the database "test"
spring.datasource.url = jdbc:mysql://localhost:3306/test?useSSL=false

# ===============================
# = JPA / HIBERNATE
# ===============================

spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true

Я попробовал все, следуя всем примерам, найденным Google. Что не так ??

Спасибо

Ответы [ 2 ]

0 голосов
/ 24 апреля 2019

решаемая.Это проблема сеанса, и есть другое решение.

Первый - это добавление аннотации выборки:

@Entity
@Data
public class User {
  private String name;
  @ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
  private List<Hobby> hobbies;
}

Таким образом, каждый раз, когда вы находите сущность пользователя, вы выбираете все связанные с ней хобби.Другое решение (намного лучше) - оставить значение выборки по умолчанию (ленивое для многих и многих отношений) и добавить @ Transactional аннотацию для метода, который вы используете для извлечения данных.

@Transactional
public void searchData() {
  User user = new User();
  user.setName("James");
  user.setHobbies(new ArrayList<>());

  Hobby hobby = new Hobby();
  hobby.setDescription("Golf");
  hobby.setUsers(new ArrayList<>());

  user.getHobbies.add(hobby);
  hobby.getUsers.add(user);

  userRepository.save(user);

  List<User> us = userRepository.findAll();
  for (User u : us) {
    System.out.println(u.getHobbies().size()); // print 1
  }
}

Надежда помогает..

0 голосов
/ 24 апреля 2019

Я думаю, вы не сохраняете хобби-сущность перед вызовом userRepository.findAll().

Если вы создаете отношения между сущностями, вам нужно сохранить все зависимые сущности до сохранения и поиска в глобальной сущности.

Если вы сохраняете сущность с NULL в зависимых полях, они не выдают исключение.В вашем случае вы сохраняете пустой список, но гибернацию не можете сохранить, потому что он проверяет FK и не находит это хобби.

Вы можете попробовать сохранить пользователя с NULL или с существующим в хобби базы данных.Вот так:

List<Hobby> hobbies = hobbyRepository.findAll();

user.getHobbies().addAll(hobbies); // null pointer exception
userRepository.save(user);

userRepository.findAll();

Я не понимаю, почему ваш репозиторий позволяет сохранять.Я использую postgres, и интерфейс расширяется в JpaRepository, и они выдают исключение, если я сохраняю пользователя с пустым списком хобби.


Я пробовал:

Hobby h = new Hobby();
h.setDesc("Golf");
hobbyRepository.save(h);

List<Hobby> hobbies = hobbyRepository.findAll();

Persona p = new Persona();
p.setNome("Giacomo");
p.setHobbies(new ArrayList<>());
p.getHobbies().addAll(hobbies);
personaRepository.save(p);

List<Persona> persone = personaRepository.findAll();
List<Hobby> hobby = hobbyRepository.findAll();

Не работает .. МожетВы сделали рабочий пример, похожий на этот ??Я буду признателен за это, потому что я не могу понять, где ошибка .. PS Если я поставлю:

@ManyToMany(fetch = FetchType.EAGER)

Это работает .. но я не хочу ставить это !!Должен работать со значениями по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...