Hibernate多对多关系中Role实体name字段数据丢失问题
多对多关联中Role实体name字段未保存的问题解决
在使用Hibernate实现多对多关联时,保存Users实体后,users表、users_roles关联表数据正常插入,但role表仅生成UUID,name字段为空。相关代码如下:
@Table(name = "users") @Entity @AllArgsConstructor @NoArgsConstructor @Data @ToString @EqualsAndHashCode public class Users implements Serializable { @Id String id; String username; String password; @ManyToMany(cascade = {CascadeType.PERSIST}, fetch = FetchType.EAGER) @JoinTable(name = "users_roles", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) private List<Role> roles = new ArrayList<>(); } @Table(name = "role") @Entity @AllArgsConstructor @NoArgsConstructor @Data @Builder @ToString @EqualsAndHashCode public class Role implements Serializable { @Id @GeneratedValue @Type(type = "uuid-char") UUID id; @Column(name = "name") String name; } @Repository public interface UsersRepository extends JpaDynamicQueryRepository<Users, String> { } public void save(){ Users users = new Users(); users.setUsername("ui-user"); users.setPassword("ui1234"); users.setId(UUID.randomUUID().toString()); Role adminRole = Role.builder() .name("ui-role") .build(); Role testRole = Role.builder() .name("ui-test-role") .build(); List<Role> roles = new ArrayList<>(); roles.add(adminRole); roles.add(testRole); users.setRoles(roles); usersRepository.saveAndFlush(users); }
问题原因
核心问题是Lombok注解冲突:Role实体同时使用@AllArgsConstructor和@Builder时,生成的Builder会依赖全参构造器,而通过Builder创建Role时未传入id参数,导致字段赋值逻辑异常,最终name字段未被正确传递到Hibernate进行持久化。
解决方案
方案1:修复Lombok注解配置
修改Role实体,移除@AllArgsConstructor,并明确UUID生成策略(避免默认策略的潜在问题):
@Table(name = "role") @Entity @NoArgsConstructor @Data @Builder(toBuilder = true) @ToString @EqualsAndHashCode public class Role implements Serializable { @Id @GeneratedValue(generator = "uuid2") @GenericGenerator(name = "uuid2", strategy = "uuid2") @Type(type = "uuid-char") UUID id; @Column(name = "name") String name; }
说明:@Builder会自动生成适配的构造器和Builder逻辑,无需@AllArgsConstructor;指定uuid2生成策略可确保UUID稳定生成。
方案2:替换Builder为手动构造
如果不想调整Lombok注解,直接使用无参构造器+setter或全参构造器创建Role:
// 方式1:无参构造器+setter Role adminRole = new Role(); adminRole.setName("ui-role"); // 方式2:全参构造器(传入null作为id,由Hibernate自动生成) Role testRole = new Role(null, "ui-test-role");
方案3:验证数据库字段配置
确认role表的name字段:
- 字段类型为
VARCHAR(或对应字符串类型),长度满足业务需求 - 若业务要求非空,需确保实体字段未标记
nullable = false(或数据库字段允许非空,否则会抛出持久化异常)
内容的提问来源于stack exchange,提问作者avinash shelke
相关产品推荐
相关产品推荐

