I know this kind of question was answered many times and there are solutions to it, however, none of them worked for me. I tried @JsonIgnore
, @JsonIgnoreProperties
@JsonManagedReference/@JsonBackedReference
, yet still the debugger shows that user
has reference to authority
, which has reference to user
, which has reference to authority
, which has reference to user
... Most importantly it doesn't throw any exceptions. However, I still wonder why does this happen, why it doesn't throw exceptions, and does it affect productivity
My entities are simple: there is a User
@Entity
@Table(name = "users_tb")
@NoArgsConstructor
@Getter
@Setter
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<Authority> authorities;
}
and Authority
@Entity
@Table(name = "authorities_tb")
@NoArgsConstructor
@Getter
@Setter
public class Authority {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
}
the code to retrieve users using JpaRepository<T, V>
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
var user = userRepository.findUserByUsername(username).orElseThrow(
() -> new UsernameNotFoundException(ERR_USERNAME_NOT_FOUND));
return new CustomUserDetails(user);
}
The debugger output state before return from loadUserByUsername
:
user = {User@10781}
> id = {Long@10784}
> username = "John"
> password = "$2a$10$xn3LI/AjqicFYZFruSwve.681477XaVNaUQbr1gioaWPn4t1KsnmG"
> authorities = {PersistentBag@10788} size = 2
> 0 = {Authority@10818}
> id = {Long@10784}
> name = "READ"
> user = {User@10784}
> id = {User@10784}
> username = "John"
> password = "$2a$10$xn3LI/AjqicFYZFruSwve.681477XaVNaUQbr1gioaWPn4t1KsnmG"
> authorities = {PersistentBag@10788} size = 2
> 0 = {Authority@10818}
...
CodePudding user response:
Try not to use the Lombok annotation @Getter and @Setter. Then generate manually getters and setters and use @JsonIgnore on the class member field and the getter, and @JsonProperty on the setter.
@JsonIgnore
private List<Authority> authorities;
@JsonIgnore
// Getter for authorities
@JsonProperty
// Setter for authorities
CodePudding user response:
You can simply annotate the duplicated field with @ToString.Exclude
In you case:
@Data // this includes getter/setter and toString
@Entity
@Table(name = "users_tb")
@NoArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
@ToString.Exclude
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<Authority> authorities;
}
@Data
@Entity
@Table(name = "authorities_tb")
@NoArgsConstructor
public class Authority {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
}
More info: Lombok @Data and @ToString.Exclude