0

For my application, i need to define these kind of profiles :

  • Salesman
  • Customer
  • Administrator

A user can have one or all these profiles. It's why i didn't choose the inheritance design, I prefered to choose a role strategy, so a user can have many roles. For example, a user can have salesman and customer role. The problem is that there are some specifics informations for each role, for example a salesman must specify his delivery adresses...

Here is a my implementation with spring security/JPA :

User model

@Entity
@Table(name = "USER")
public class User implements UserDetails{

    @Id 
    @Column(name = "USER_ID")
    private Long id;

     @ManyToMany(fetch = FetchType.EAGER)
     @JoinTable(
          name="USER_ROLE",
          joinColumns={@JoinColumn(name="USER_ID", referencedColumnName="USER_ID")},
          inverseJoinColumns={@JoinColumn(name="USER_ROLE_ID", referencedColumnName="ROLE_ID")})
    private Set<Role> roles = new HashSet<Role>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Set<Role> getRoles() {
        return roles;
    }

    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.addAll(roles);
        return authorities;
    } 
}

role model

@Entity
@Table(name = "ROLE")
public class Role implements GrantedAuthority {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ROLE_ID")
    private Long idRole;

    @Column(name = "TYPE_ROLE")
    private String typeRole;

    public Long getIdRole() {
        return this.idRole;
    }

    public void setIdRole(Long idRole) {
        this.idRole = idRole;
    }

    public String getTypeRole() {
        return this.typeRole;
    }

    public void setTypeRole(String typeRole) {
        this.typeRole = typeRole;
    }

    @Override
    public String getAuthority() {
        return typeRole;
    } 
}

I cannot define specific fields for each role because the class Role is generic, i don't want to mix fields of all role in one role, i prefer to encapsulate each specific fields in each role. I don't want too store all fields of all role mixed in one table in database because each role have his specifics constraints. How should i do ?

icedwater
  • 4,701
  • 3
  • 35
  • 50
julus
  • 431
  • 1
  • 5
  • 14

1 Answers1

0

I found a average solution, i can use composition for each kind of profiles.

    @Entity
    @Table(name = "USER")
    public class User implements UserDetails{

    @Id 
    @Column(name = "USER_ID")
    private Long id;

    @OneToMany
    private SalesmanProfile salesmanProfile;

    @OneToMany
    private CustomerProfile customerProfile;

    public Long getId() {
        return id;
    } 
    public void setId(Long id) {
        this.id = id;
    } 
}


@Entity
@Table(name = "SALESMAN_PROFILE")
public class SalesmanProfile{

    @Id
    @Column(name = "SALESMAN_PROFILE_ID")
    private Long id;

    @ManyToOne
    @JoinColumn(name = "USER_ID", nullable = false)
    private User user;

    private SpecificsFields.....

}

Same for CustomerProfile...

If i want know if a user is a salesman i can check if user's salesman profile is not null... What do you think?

julus
  • 431
  • 1
  • 5
  • 14