1
resposta

Como eu poderia criar o default schema no código, sem ser diretamente no banco de dados?

Eu imaginei algo mais ou menos assim para o UserCredentials:

@Entity
@Table(name = "user_credentials")
public class UserCredentials implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    private String username;
    private String senha;
    private boolean enabled;
    @JsonIgnore
    @OneToMany(mappedBy = "userCredentials")
    List<Authorities> userAuthorities = new ArrayList<>();

    public UserCredentials() {
    }

    public UserCredentials(String username, String senha, boolean enabled) {
        this.username = username;
        this.senha = senha;
        this.enabled = enabled;
    }

    public String getUsername() {
        return username;
    }

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

    public String getSenha() {
        return senha;
    }

    public void setSenha(String senha) {
        this.senha = senha;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}

E algo assim para o Authorities:

@Entity
@Table(name = "authorities")
public class Authorities {

    @ManyToOne
    @JoinColumn(name = "username")
    private UserCredentials userCredentials;
    private String authority;

    public Authorities() {
    }

    public Authorities(UserCredentials userCredentials, String authority) {
        this.userCredentials = userCredentials;
        this.authority = authority;
    }

    public UserCredentials getUserCredentials() {
        return userCredentials;
    }

    public void setUserCredentials(UserCredentials userCredentials) {
        this.userCredentials = userCredentials;
    }

    public String getAuthority() {
        return authority;
    }

    public void setAuthority(String authority) {
        this.authority = authority;
    }
}

Isso faz sentido? Funcionaria corretamente em uma situação real supondo que um usuário poderia ter mais de uma permissão?

1 resposta

Sim, é uma possibilidade, só faria algumas observações:

O mais comum é nomear as Entidades do JPA no singular, então em vez de Authorities colocaria Authority

Outro ponto é que se tentar subir assim o JPA vai reclamar que a classe Authorities não tem um campo definido como identificador.

Aqui surgem algumas possibilidades, vc poderia criar um campo id no banco e mapear, ou então mapear a classe Authorities como @Embeddable

Exemplo:

@Embeddable
public class Authority {

    private String authority;

    public Authority() {
    }

    public Authority(String authority) {
        this.authority = authority;
    }

    //gets e sets...

}

E no usuário vc mapearia como:

@Entity
@Table(name = "users")
public class User {

    @Id
    @NotBlank
    private String username;

    @NotBlank
    private String password;
    private Boolean enabled;

    @ElementCollection
    @CollectionTable(name = "authorities", joinColumns = @JoinColumn(name = "username"))
    private Set<Authority> authorities = new HashSet<>();
 // gets e sets
 }

Observe que por mais que um usuário tenha várias authorities não há motivos para elas serem repetidas, então vc pode trocar o List por Set.

Por fim, é importante frisar que em projetos reais nunca utilizam o hibernate pra criar/atualizar a estrutura do banco, já que ele não faz uma atualização mto "confiável". Por ex, uma tabela que já existe e tem registros, se vc criar um novo campo mapeado como not null ele não saberá o que preencher e provavelmente não criará a coluna.. O padrão é usar alguma ferramenta específica para migração de banco como Flyway e LiquidBase.