I have the following method, which behind scenes uses Jackson to parse the list of entities to json:
@Controller
@RequestMapping("/user/")
public class EditarLugarController {
@RequestMapping(value = "stores/{id}/branches", method = RequestMethod.GET)
public @ResponseBody List<Branch> renderBranchesPerStore(@PathVariable(value = "id") Integer id) {
if(branches == null) {
//get branches based on store's id
}
return branches;
}
This method is called from the view through ajax using jquery
var idBranch = '${store.id}';
$.get("http://localhost:8080/myapp/user/stores/" + idBranch+ "/branches",
function(data) {
// show json objects in page
});
The problem is that when this method ends, it throws the following exception:
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:639)
I tried removing the @PathVariable (returning some default value) and it works ok, but I need that parameter. Is there a workaroung to this issue?
EDIT: here's the branch code as requested, but again: I DONT think it's related to the issue because if I don't use @PathVariable it works ok, the list of Branches is parsed ok to json and sent to the view. Also, I'm using a Jackson plugin for Hibernate that tells Jackson not to parse attributes that are lazy loaded, to prevent exceptiosn
@Entity
@Table(name = "BRANCH")
public class Branch implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="BRANCH_ID")
@GeneratedValue(strategy= GenerationType.TABLE)
private Integer id;
@Column(name = "DESCRIPTION")
@Size(max = 500)
private String description;
@Column(name="STREET")
@NotNull
@Size(max = 100)
private String street;
@Column(name="NUMBER")
@NotNull
@Size(max = 6)
private String number
@Column(name="FLOOR")
@Size(max = 3)
private String floor;
@Column(name="APT")
@Size(max = 10)
private String apt
@OneToMany(cascade = CascadeType.ALL, mappedBy="branch")
private List<BranchPhoto> photos;
@JoinColumn(name = "STORE_FK", referencedColumnName = "STORE_ID")
@ManyToOne(optional = false)
private Store store;
public Branch() {}
// getters & setters
}
EDIT: I've realized that even without PathVariable it thorws same exception, I must have tested that wrong. So the problem actually is for circular reference while parsing json
As NimChimpsky said, problem was caused for circular references in the model, in class Branch. Besides using dtos to make serialization simple, another solution for those who do not want to use DTOs (like me) is to use some annotations to tell Jackson how to handle the attributes. these are the annotations needed:
In class Store, the attribute branches:
@OneToMany(mappedBy = "store", cascade = CascadeType.ALL)
@JsonManagedReference // this annotation prevents the exception
private List<Branch> branches
And in class Branch, in the attribute store:
@JoinColumn(name = "LUGAR_FK", referencedColumnName = "LUGAR_ID")
@ManyToOne(optional = false)
@JsonBackReference // this annotation prevents the exception
private Lugar lugar;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With