You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 10:15:06