0

The issue is that the enum values are not being saved in the database, so whenever I register new user it returns user with 0 role size even though I have all the right configurations, so came to the root cause which is enum values of ERole not being saved in the database and the Role table is empty.

ERole enum:

public enum ERole {
    ROLE_USER,
    ROLE_MODERATOR,
    ROLE_ADMIN
}

Role entity:

@EqualsAndHashCode
@NoArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "roles")
public class Role implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Enumerated(EnumType.STRING)
    @Column(length = 20)
    private ERole role;
    @ManyToMany(mappedBy="roles")
    private List<User> users = new ArrayList<>();
    public Role(ERole role) {
        this.role = role;
    }
}

User entity:

@Getter
@Setter
@NoArgsConstructor
@EqualsAndHashCode
@Entity
@Table(name = "users",
        uniqueConstraints = {
                @UniqueConstraint(columnNames = "name"),
        })
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private String pass;

    @JsonIgnoreProperties("users")
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "user_roles",
            joinColumns = { @JoinColumn(name = "user_id") },
            inverseJoinColumns = { @JoinColumn(name = "role_id") })
    private List<Role> roles = new ArrayList<>();
    public User(String name, String pass) {
        this.name = name;
        this.pass = pass;
    }
}

As you see below in the diagram Role entity has the role column with ERole type enter image description here

I have seen the oter similar threads where it is suggested to use the @Enumerated(EnumType.STRING) which I've been using in the first place.

Nara Omur
  • 21
  • 7
  • As your `roles` table does not hold any additional information, why not replace it with a table that holds the userId and the enum string? No need for the join table as well as making the mapping easier – XtremeBaumer Jan 26 '23 at 09:53
  • Do you mean to change the whole logic now, user can have several roles as well as the role has several users whereas with one table having user-id and the roles would be not good in terms of readability of the logic, I think – Nara Omur Jan 26 '23 at 10:54
  • Does this answer your question? [Hibernate mapping between PostgreSQL enum and Java enum](https://stackoverflow.com/questions/27804069/hibernate-mapping-between-postgresql-enum-and-java-enum) – XtremeBaumer Jan 26 '23 at 14:03
  • Just saw that you are mapping it to an ENUM column in postgres. Hibernate doesn't natively support a mapping to this AFAIK. Link above shows how to handle that. `@Enumerated(EnumType.STRING)` tells hibernate how you want to persist the java enum in the database. `EnumType.STRING` persists it as a string, mapping to a `varchar` column. `EnumType.ORDINAL` persists as a number, usually mapping to a `numeric` column – XtremeBaumer Jan 26 '23 at 14:06
  • 1
    You can either change the column type in your database to `varchar` to get the enum value persisted. Or you implement the [custom-type](https://vladmihalcea.com/the-best-way-to-map-an-enum-type-with-jpa-and-hibernate/) – XtremeBaumer Jan 26 '23 at 14:10

1 Answers1

0

I know it's been a while but recently saw this question in my profile without closure and flashed back on how I solved this and moved on.

So as @XtremeBaumer mentioned about varchar I got an idea just to make table roles as a dictionary that will hold static data or rarely modify. So I just inserted the three levels of roles as VARCHAR values and the hibernate many-to-many mapping did the rest of the magic on joining table user_roles.

Nara Omur
  • 21
  • 7