Spring MVC / Jackson - weird superstition
I am having a weird problem with Jackson serialization - I have an object Role
that has a nested Permission entity
object, which in turn contains a nested object Metadata
. When these objects are retrieved from Spring MVC @RestController
as a list, Jackson serializes the collection Permission
to a JSON array. The problem is that sometimes the element placed in this array is just an identifier Permission
and not a serialized representation of the object.
Role.class:
@Entity
@Table(name = "t_db_roles")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Role.class)
public class Role implements GrantedAuthority {
private final static Logger log = LoggerFactory.getLogger(Permission.class);
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "auto_id")
private int id;
@Column(name = "role", length = 50)
private String name;
@OneToMany(fetch = FetchType.EAGER)
@JoinTable(name = "t_db_role_permissions",
joinColumns = {@JoinColumn(name = "roleid", referencedColumnName = "auto_id")},
inverseJoinColumns = {@JoinColumn(name = "permid", referencedColumnName = "auto_id")}
)
private Set<Permission> permissions;
// getters and setters omitted
}
Permission.class:
@Entity
@Table(name = "t_db_permissions")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Permission.class)
public class Permission implements GrantedAuthority {
private final static Logger log = LoggerFactory.getLogger(Permission.class);
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "auto_id")
private int id;
@Column(name = "name")
private String name;
@OneToOne(mappedBy = "permission")
private Metadata metadata;
}
Metadata.class
@Entity
@Table(name = "t_report_data")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Metadata.class)
public class Metadata {
@Id
@Column(name = "id", insertable = false, updatable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "file_name")
private String fileName;
@Column(name = "human_name")
private String humanName;
@Column(name = "links_to")
@JsonIgnore
private Integer linksTo;
@Column(name = "is_subreport")
@JsonIgnore
private Boolean isSubreport;
@OneToOne(cascade = javax.persistence.CascadeType.ALL, fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "permid")
private Permission permission;
}
Controller:
@RestController
public class RoleRestController {
private final static Logger log = LoggerFactory.getLogger(PermissionRestController.class);
private RoleService roleService;
private MetadataService metadataService;
@Autowired
public void setRoleService(RoleService service) {
this.roleService = service;
}
@Autowired
public void setMetadataService(ReportMetadataService service) { this.metadataService = service; }
@RequestMapping(value = "/admin/roles/", method = RequestMethod.GET)
public List<Role> getRoles() {
return roleService.getRoles();
}
}
I'm pretty sure the issue is with serialization - repeating the command List<Role>
in the console works as expected, but here's the JSON returned (note that the first element of the permissions array is an integer, not a JSON object):
{
"id": 10,
"name": "ROLE_TESTER",
"permissions": [
14,
{
"id": 7,
"name": "ViewDailySettlementSummaryGL",
"metadata": {
"id": 41,
"fileName": "acct_summary_gl.rptdesign",
"humanName": "Daily Settlement Summary GL",
"permission": 7
},
"authority": "ViewDailySettlementSummaryGL"
},
{
"id": 6,
"name": "ViewDailySettlementSummary",
"metadata": {
"id": 24,
"fileName": "acct_summary_os.rptdesign",
"humanName": "Daily Settlement Summary",
"permission": 6
},
"authority": "ViewDailySettlementSummary"
}
],
"authority": "ROLE_TESTER"
}
I can work around this by handling the serialization Role
manually, but since SpringMVC / Jackson serialization works for other classes in the project, it looks like there must be an issue in those classes that I am missing. Any ideas?
source to share
No one has answered this question yet
Check out similar questions: