Chaibi Alaa
Chaibi Alaa

Reputation: 1386

Default Constructor unfound in Spring

I just moved my class to an object which uses an extend to Spring Security Authentication User class, and I can't figure out which default constructor I need to build ! If I put parameters of the class, it transforms them to static and make hibernate unable to map the class, if I put nothing, it throws an error !

@Entity
@Table(name="USER") 
public class UserData extends User {


    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    int iduser;
    int accountstatus;
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPass(String password) {
        this.password = password;
    }
     String username;
     String password;

    //Profile Data
    String nomprofile;
    String prenprofile;
    String mailprofile;
    String adressprofile;
    int phoneprofile;
    Date datenaissanceprofile;
    char sexeuser;
    String imagepath;

    public UserData() {
        super(username, password, authorities); //throws error 
    }

    public UserData(String username, 
            String password, 
            boolean enabled, 
            boolean accountNonExpired, 
            boolean credentialsNonExpired, 
            boolean accountNonLocked, 
            Collection<? extends GrantedAuthority> authorities, 
            int iduser,     
            int accountstatus,
            String nomprofile, 
            String prenprofile,
            String mailprofile,
            String adressprofile,
            int phoneprofile, 
            Date datenaissanceprofile, 
            char sexeuser,
            String imagepath) {
        super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
        this.username = username;
        this.password = password;
        this.iduser = iduser;
        this.accountstatus = accountstatus;
        this.nomprofile = nomprofile;
        this.prenprofile = prenprofile;
        this.mailprofile = mailprofile;
        this.adressprofile = adressprofile;
        this.phoneprofile = phoneprofile;
        this.datenaissanceprofile = datenaissanceprofile;
        this.sexeuser = sexeuser;
        this.imagepath = imagepath;
    }

    public int getIduser() {
        return iduser;
    }
    public void setIduser(int iduser) {
        this.iduser = iduser;
    }


    public int getAccountstatus() {
        return accountstatus;
    }
    public void setAccountstatus(int accountstatus) {
        this.accountstatus = accountstatus;
    }


    public String getNomprofile() {
        return nomprofile;
    }
    public void setNomprofile(String nomprofile) {
        this.nomprofile = nomprofile;
    }
    public String getPrenprofile() {
        return prenprofile;
    }
    public void setPrenprofile(String prenprofile) {
        this.prenprofile = prenprofile;
    }
    public String getMailprofile() {
        return mailprofile;
    }
    public void setMailprofile(String mailprofile) {
        this.mailprofile = mailprofile;
    }
    public String getAdressprofile() {
        return adressprofile;
    }
    public void setAdressprofile(String adressprofile) {
        this.adressprofile = adressprofile;
    }
    public int getPhoneprofile() {
        return phoneprofile;
    }
    public void setPhoneprofile(int phoneprofile) {
        this.phoneprofile = phoneprofile;
    }
    public Date getDatenaissanceprofile() {
        return datenaissanceprofile;
    }
    public void setDatenaissanceprofile(Date datenaissanceprofile) {
        this.datenaissanceprofile = datenaissanceprofile;
    }
    public char getSexeuser() {
        return sexeuser;
    }
    public void setSexeuser(char sexeuser) {
        this.sexeuser = sexeuser;
    }
    public String getImagepath() {
        return imagepath;
    }
    public void setImagepath(String imagepath) {
        this.imagepath = imagepath;
    }
}

Upvotes: 0

Views: 1822

Answers (3)

Anudeep Gade
Anudeep Gade

Reputation: 1395

I prefer to separate entity and security related data handlers.

@Entity
public class UserEntity {}

public class SecureUserPrinicipal extends org.spring..User {
    public SecureUserPrinicipal  getSecureUserPrincipal(final UserEntity userEntity){
        return new SecureUserPrinicipal(userEntity.getUsername(),.....);    
    }

 } 

Pros:

  1. Clear separation of model and security layers and reusable components.
  2. SecureUserPrinicipal just needs security related fields not all UserEntity fields like sex,phone etc.
  3. We can have separate aspects on each class like loggers, statistics etc.
  4. Testable separately.
  5. Transactions,hibernate session magic will work on UserEntity, Example : if user changes the password UserEntity will be persisted, do you want to invalidate the currently logged in SecureUserPrincipal because of that, not sure right ? Managing users db and managing logged in user sessions principals are different.

Cons: If UserEntity evolves, we need to adapt SecureUserPrinicipal if that field is involved in security stuff very rare.

Upvotes: 0

Nalla Srinivas
Nalla Srinivas

Reputation: 933

Instead of extending user class from spring-security you better to implement UserDetails interface given from spring security. please read the below code. Provide custom userDetailsService implementation to your project. i hope this will help you- http://docs.spring.io/spring-security/site/docs/3.0.x/reference/technical-overview.html#d0e1613

 public class User implements UserDetails{

private UserData userData;
private List<String> roles;

public User(UserData user){
    this.userData=user;

}



public Collection<? extends GrantedAuthority> getAuthorities() {
    List<SimpleGrantedAuthority> authorities=new ArrayList<SimpleGrantedAuthority>();
    for (String role : userData.getRoles()) {
        authorities.add(new SimpleGrantedAuthority(role));
    }
    return authorities;
}

public String getPassword() {
    return user.getPassword();
}

public String getUsername() {
    // TODO Auto-generated method stub
    return user.getUsername();
}

public boolean isAccountNonExpired() {
    // TODO Auto-generated method stub
    return true;
}

public boolean isAccountNonLocked() {
    // TODO Auto-generated method stub
    return true;
}

public boolean isCredentialsNonExpired() {
    // TODO Auto-generated method stub
    return true;
}

public boolean isEnabled() {
    // TODO Auto-generated method stub
    return true;
}

}

Upvotes: 2

Jacob Briscoe
Jacob Briscoe

Reputation: 252

Can you provide the error stacktrace? It might help to resolve this issue.

I take it this is the class you are extending: org.springframework.security.core.userdetails.User? If so, it has 2 constructors, which you are free to override in your code when constructing new instances. If you override them, I encourage you to call super on each since they actually perform initialization of the instance. For example:

public UserData(String username, String password, Collection<? extends GrantedAuthority> authorities) {
    super(username, password, authorities);
    // Your code here.
}

public UserData(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
    super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
    // Your code here.
}

But since Hibernate won't call those constructors for you by default, you need to provide a no-arg constructor. For this I would add it like so:

UserData() {
    // Hibernate
}

Hibernate should be able to load your persisted class.

Update:

Ok, I see the problem and have a solution. Remove your existing code:

public UserData() { super(username, password, authorities); //throws error }

replace it with:

public UserDetail(){ this(null, null, null); }

Upvotes: -1

Related Questions