HibernateJpaConfiguration java.lang.NullPointerException当我使用2多个关系时
我有以下表格:HibernateJpaConfiguration java.lang.NullPointerException当我使用2多个关系时,hibernate,spring-data-jpa,Hibernate,Spring Data Jpa,我有以下表格: 使用者 角色 房间 用户+角色和用户+房间应通过@manytomy表进行映射 当我创建用户和角色实体时,所有实体都运行良好 用户 @Entity @Table(name = "user") public class User extends BaseEntity { //......... @ManyToMany @JoinTable(name = "user_role", joinColumns = {@Jo
- 使用者
- 角色
- 房间
用户
+角色
和用户
+房间
应通过@manytomy
表进行映射
当我创建用户
和角色
实体时,所有实体都运行良好
用户
@Entity
@Table(name = "user")
public class User extends BaseEntity {
//.........
@ManyToMany
@JoinTable(name = "user_role",
joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")}
)
private Set<UserRole> roles;
@ManyToMany
@JoinTable(name = "user_room",
joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "room_id", referencedColumnName = "id")}
)
private Set<Room> rooms;
房间
@Entity
@Table(name = "room")
public class Room extends BaseEntity{
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(
name = "UUID",
strategy = "org.hibernate.id.UUIDGenerator",
parameters = {
@org.hibernate.annotations.Parameter(
name = "uuid_gen_strategy_class",
value = "org.hibernate.id.uuid.CustomVersionOneStrategy"
)
}
)
@Column(name = "id")
private String id;
@ManyToMany(mappedBy = "rooms")
private Set<User> userList;
@实体
@表(name=“房间”)
公共教室扩展为基本实体{
@身份证
@GeneratedValue(generator=“UUID”)
@通用生成器(
name=“UUID”,
strategy=“org.hibernate.id.UUIDGenerator”,
参数={
@org.hibernate.annotations.Parameter(
name=“uuid\u gen\u strategy\u class”,
value=“org.hibernate.id.uuid.CustomVersionNestStrategy”
)
}
)
@列(name=“id”)
私有字符串id;
@许多(mappedBy=“房间”)
私有集用户列表;
我有以下例外:
org.springframework.beans.factory.BeanCreationException:错误
创建在类路径中定义了名为“entityManagerFactory”的bean
资源
[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]:
调用init方法失败;嵌套异常为
java.lang.NullPointerException
我已经在尝试使用
LAZY
,EAGER
方法,@Proxy(LAZY=false)
和许多其他属性。但没有什么不帮助我解决这个问题。我看到的主要问题是您没有正确设置mappedBy=
属性。该值应该是拥有的实体中的字段名称,例如房间,而不是房间
@ManyToMany(mappedBy = "rooms")
private Set<User> userList;
及
mappedBy
注释指定所属实体
拥有关系的字段。除非关系是单向的,否则为必填项
您自始至终都使用了双向
映射,因此您使用的是mappedBy
注释。拥有实体的含义是负责持久化关系的实体。在您的示例中,Room
负责持久化创建者
关系,用户
负责per显示用户角色
关系。最终结果可能是
@Entity
public class User {
@ManyToMany
@JoinTable(name = "user_role",
joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")}
)
private Set<Role> roles;
@OneToMany(mappedBy="creator")
private Set<Room> rooms;
@Entity
public class Role {
@ManyToMany(mappedBy = "roles")
private Set<User> users;
@Entity
public class Room {
@ManyToOne
private User creator;
请注意,在使用特定实例而不刷新它时,必须专门管理双向关系的两侧:
Java持久性API要求在关系的两侧设置引用,这意味着您必须显式地调用b.setA(a)和a.setB(b)
因此u1.setRooms(Collections.singleton(m1))和r1.setUsers(Collections.singleton(u1))添加;,以便当前用户和角色实例将具有准确的文件室和用户集合。如果这些实例稍后将通过对JPA的新调用从数据库重新加载,这是典型的,那么这些将不是必需的。谢谢!!关于急切的
类型用法:当我不使用它时,我会得到类似“LazyInitializationError”(在每个(!)项目中)@Valentynhruzytsky如果我检查这一点,当尝试访问尚未专门获取的关系时,会发生lazy init异常。你需要学习如何专门获取你想要访问的关系。我已经看到了在存储库中使用@EntityGraph来处理此问题的好方法。请检查我的答案
@OneToMany(mappedBy="creator")
private Set<Room> rooms;
@ManyToOne
private User creator;
@Entity
public class User {
@ManyToMany
@JoinTable(name = "user_role",
joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")}
)
private Set<Role> roles;
@OneToMany(mappedBy="creator")
private Set<Room> rooms;
@Entity
public class Role {
@ManyToMany(mappedBy = "roles")
private Set<User> users;
@Entity
public class Room {
@ManyToOne
private User creator;
Role r1 = new Role();
roleRepo.save(r1);
User u1 = new User();
// needed to persist relation
u1.setRoles(Collections.singleton(r1));
// added to improve accuracy
r1.setUsers(Collections.singleton(u1));
userRepo.save(u1);
Room m1 = new Room();
// needed to persist relation
m1.setCreator(u1);
// added to improve accuracy
u1.setRooms(Collections.singleton(m1));
roomRepo.save(m1);