Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

JSON traz relacionamento recursivos infinito

Olá Rodrigo.

Fiz um mapeamento ManyToMany para o Spring Security junto com o oAuth2 e ao buscar um Principal através de um token, ele retorna um encadeamento infinito, conforme exemplo JSON abaixo:

{
    "authorities": [
        {
            "id": {
                "userId": 1,
                "roleId": 1
            },
            "user": {
                "id": 1,
                "name": "Bruno",
                "email": "mail@gmail.com",
                "password": "$2a$10$hIOcJxKMHBKxRM2LqPuwsi1B6wdXjwQggxdy9",
                "active": true,
                "enabled": true,
                "authorities": [
                    {
                        "id": {
                            "userId": 1,
                            "roleId": 1
                        },
                        "user": {
                            "id": 1,
                            "name": "Bruno",
                            "email": "mail@gmail.com",
                            "password": "$2a$10$hIOcJxKMHBKxRM2LqPuwsi1B6wdXjwQggxdy9.",
                            "active": true,
                            "enabled": true,
                            "authorities": [
                                         (...)

Mapeamentos:

Classe User:

@Entity
public class User  implements UserDetails {
    (...)

    @OneToMany(mappedBy = "user", fetch = FetchType.EAGER)
    private Set<UserRole> roles = new HashSet<>();
}

Classe Role:

@Entity
public class Role {
    (...)

    @OneToMany(mappedBy = "role", fetch = FetchType.LAZY)
    private Set<UserRole> users = new HashSet<>();

Classe Associativa:

@Entity
@Table(schema = DBConfigurations.DB_SCHEMA, name = "tb_user_role")
public class UserRole implements GrantedAuthority {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private UserRoleKey id;

    @ManyToOne
    @MapsId("userId")
    @JoinColumn(name = "id_user")
    private User user;

    @ManyToOne
    @MapsId("roleId")
    @JoinColumn(name = "id_role")
    private Role role;

    @Column(name = "dt_begin")
    private LocalDateTime dtBegin;

    @Column(name = "dt_end")
    private LocalDateTime dtEnd;

    @Column(name = "in_active")
    private Boolean isActive;

    (...)

Por que traz esse mapeamento infinito? Como resolver? Muito obrigado!

2 respostas

Oi Bruno,

Isso acontece porque você deve estar retornando a entidade JPA ao invés de um DTO, como foi mostrado no curso.

E como uma entidade pode ter relacionamentos bidirecionais, pode acontecer um loop infinito.

O ideal é criar uma classe DTO apenas com os atributos que você deseja retornar.

Bons estudos!

solução!

Muito obrigado pelo rápido retorno.

Fiz a alteração para retornar DTO simulando um Principal e deu certo, conforme exemplo abaixo:

    @Override
    public OAuth2AuthenticationDto user(Principal user) {
        //O parâmetro "user" é injetado pelo Spring.
        OAuth2Authentication userPrincipal = (OAuth2Authentication) user;
        return new OAuth2AuthenticationDto(userPrincipal);
    }

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software