I am having a problem with the jackson deserializer.
I have two spring boot applications and a separate module for the shared model.
app1-> <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>eu.emif.security</groupId>
<artifactId>model</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
app2-> <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>eu.emif.security</groupId>
<artifactId>model</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
model-> <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.0</version>
</dependency>
in the model I have a User and Role object
package eu.emif.security.model;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.annotate.JsonProperty;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Entity
@Table(name = "user", schema = "public")
@JsonAutoDetect(value = JsonMethod.NONE)
public class User implements Serializable, UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@JsonProperty
private Long id;
@NotNull
@JsonProperty
private String username;
@NotNull
private String password;
@ManyToMany(fetch = FetchType.EAGER,mappedBy = "users")
@JsonIgnore
private List<Role> roles;
public User() { }
@JsonIgnore
public Collection<? extends GrantedAuthority> getAuthorities() {
ArrayList<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
for (Role role : roles) {
grantedAuthorities.add(new SimpleGrantedAuthority(role.getRoleName()));
}
return grantedAuthorities;
}
public boolean isAccountNonExpired() {
return true;
}
public boolean isAccountNonLocked() {
return true;
}
public boolean isCredentialsNonExpired() {
return true;
}
public boolean isEnabled() {
return true;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public Long getId() {
return id;
}
}
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.annotate.JsonProperty;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
@Entity
@Table(name = "role", schema = "public")
@JsonAutoDetect(value = JsonMethod.NONE)
public class Role implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@JsonProperty
private Long id;
@ManyToMany
@JoinTable(name="user_roles", joinColumns=@JoinColumn(name="role_id"), inverseJoinColumns=@JoinColumn(name="user_id"))
@JsonIgnore
private List<User> users;
public Role() {
}
@JsonProperty
private String roleName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
The problem is that when I run my application I get a stack overflow exception because when the user object is serialized jackson then tries to serialize the roles which in turn have users and it infinite loops.
I believe the @JsonIgnore annotation is ignored (no pun intended)
Does anyone of you have an idea why this is occurring?
Is their a way of telling jackson in spring boot where it needs to look for classes which are annotated which jackson annotations. I believe that the mapper in app1 simply has no idea that their are classes in the separate module which are annotated.
From your pom.xml it seems that you're using Jackson 2.x but the annotations are from the old Jackson (1.xx). Could you please try the following:
Change
import org.codehaus.jackson.annotate.JsonIgnore;
to
import org.fasterxml.jackson.annotate.JsonIgnore;