我有SpringBoot 2.1.3 + MySql 5.7数据库。我正在尝试在2个实体之间建立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);
所有三个表(用户表,Hobby表和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找到的所有示例尝试了所有方法。 怎么了?
谢谢
答案 0 :(得分:0)
我认为您在致电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();
不工作。.你能做一个与此示例类似的工作示例吗?我将不胜感激,因为我不明白错误在哪里。 附言如果我放:
@ManyToMany(fetch = FetchType.EAGER)
它有效..但是我不想放它!!它应该使用默认值。
答案 1 :(得分:0)
已解决。这是一个Session问题,有不同的解决方案。
首先是添加访存注释:
@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
}
}
希望有帮助。