VRaptor - XStream CircularReferenceException

tenta adicionar esse converter no XStream:

xstream.registerConverter(new CollectionConverter() {
    @Override
    public boolean canConvert(Class type) {
         return Collection.class.isAssignableFrom(type); //pode deixar só o persistentBag tb
    }

    @Override
    public void marshall(Object obj, HSW writer, MC ctx) {
         Collection collection = (Collection) obj;
         super.marshall(new ArrayList(collection), writer, ctx);
    }
});

o XStream funciona muito bem com ArrayList, talvez isso resolva o problema.

Abraços

Oi pessoal,

Vocês conseguiram resolver/entender o problema que vocês relataram nessa thread? É que estou tendo um problema muito parecido.
Tenho um modelo idêntico, uma classe DEPARTAMENTO com um relacionamento OneToMany com a REUNIAO.
Mas quando chamo esse meu código de serialização tudo funciona com esperado, ou seja, a List não é serializada e nem recebo exceção:

    @Path("/depto/lista2.json")
	public void lista2Json(){
        result.use(Results.json()).withoutRoot().from(dao.selectByNamedQuery("selectDepartamentos")).serialize();
    }

Mas como estou usando o jqGrid na interface, eu resolvi criar uma classe pra encapsular meu resultado acrescentando outros campos esperados pelo plugin do jQuery.
Eis abaixo a dita cuja e em seguida o meu método do controller que gera a exceção CircularReferenceException. Se tiverem alguma dica, eu agradeço.
Valeu!

public class jqGridJSONObj {
	
	private int page;
	private int total;
	private int records;
	
	@SuppressWarnings("unchecked")
	private List rows;
	
	public int getPage() {
		return page;
	}
	public void setPage(int page) {
		this.page = page;
	}
	public int getTotal() {
		return total;
	}
	public void setTotal(int total) {
		this.total = total;
	}
	public int getRecords() {
		return records;
	}
	public void setRecords(int records) {
		this.records = records;
	}
	@SuppressWarnings("unchecked")
	public List getRows() {
		return rows;
	}
	@SuppressWarnings("unchecked")
	public void setRows(List rows) {
		this.rows = rows;
	}
}

O método do controller:

@Path("/depto/lista.json") public void listaJson(){ List<BaseEntity> departamentos = dao.selectByNamedQuery("selectDepartamentos"); jqGridJSONObj dto = new jqGridJSONObj(); dto.setPage(1); dto.setTotal(departamentos.size()); dto.setRecords(departamentos.size()); dto.setRows(departamentos); result.use(Results.json()).withoutRoot().from(dto).include("rows").exclude("reunioes").serialize(); }
PS: Com ou sem o exclude(“reunioes”) a exceção é a mesma. E o resultado que aparece no browser é esse:
{“page”: 1,“total”: 1,“records”: 1,“rows”: [{“id”: 1,“nome”: “Financeiro”,“logradouro”: “Rua xxx”,“numero”: “1”,“complemento”: “”,“bairro”: “xxxxx”,“cidade”: “Rio de Janeiro”,“uf”: “RJ”,“pais”: “Brasil”,“reunioes”: [false,{"@class": “departamento”

dá um exclude(“rows.reunioes”)

The same exception, no donuts for you :o)

@Path("/depto/lista.json") public void listaJson(){ List<BaseEntity> departamentos = dao.selectByNamedQuery("selectDepartamentos"); jqGridJSONObj dto = new jqGridJSONObj(); dto.setPage(1); dto.setTotal(departamentos.size()); dto.setRecords(departamentos.size()); dto.setRows(departamentos); result.use(Results.json()).withoutRoot().from(dto).include("rows").exclude("rows.reunioes").serialize(); }

Uma coisa estranha que eu achei no Stacktrace é que em uma das linhas da pilha é do XStream.toXML(), normal?

at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:38)
at com.thoughtworks.xstream.XStream.marshal(XStream.java:837)
at com.thoughtworks.xstream.XStream.marshal(XStream.java:826)

at com.thoughtworks.xstream.XStream.toXML(XStream.java:801)

Obrigado

muito estranho… ele não deveria nem tentar serializar a lista de reuniões, listas são excluidas por padrão…

tenta fazer um teste só pra esse caso:

troque o List rows para List

PS: o toXML gera um json, dependendo da configuração :wink:

Na mosca, Lucas.
Só pra registrar, antes de tentar com a classe List eu tentei com um List, sendo BaseEntity uma classe abstrata da qual Departamento herda, mas deu o mesmo problema de referência circular.
Tem alguma explicação pra esse comportamento?

Obrigado

tem, o VRaptor só consegue descobrir o tipo que está declarado no field da classe jqGridJSONObj. Não tem como saber qual é o tipo genérico da instancia de List (isso é apagado em tempo de execução)

então o VRaptor não consegue descobrir qual é o tipo certo, e excluir os campos