ArticleDirectory
Problems caused by calling one-to-multiple associations through WebService: a cycle is detected in the object graph
Exception details:
Org. Apache. cxf. Interceptor. fault: Checking alling error: a cycle is detected in the object graph. This will cause infinitely deep XML:
CN. jssms. Platform. model. system. appuser @ 75fce7->
CN. jssms. Platform. model. system. approle @ 195266b->
CN. jssms. Platform. model. system. appuser @ 75fce7
Appuser --> approle --> appuser
After checking the information on the Internet, I found that there are associations between the two VO classes, which may be 1: N or N: 1. It should be related to hibernate reflection.
[Transfer]
Loop reference:
The relationship between parent and child is 1: N. Parent contains a child list. Child has a reference to parent, so there is a circular reference relationship between the two objects.
We cannot directly expose the objects with loops to WebService, because this will cause the final stack overflow in the endless loop when the XML is generated, therefore, cxf detects that the object has cycle and throws an exception to prevent further WebService release. (in the past, xfire was not so smart. It has no detection mechanism. serialization of XML results directly results in outofmemory ).
How can this problem be solved? It is to break this ring and go to a certain end. How to do this without disrupting the original design is to use@ Xmltransient
This annotation will indicate that this field should not be parsed into XML. All the tags that you do not want to parse into WebService can be marked through this tag.
Note: by default, cxf uses jaxb for databindings. If Aegis is to be used, @ ignoreproperty is used for Metadata Annotation.
In this case, we generally need to break the child's reference to the parent, that is, to break the child's reference to the parent..Note that you should add the get method of the parent instead of the declaration of the parent.
In this way, we cannot see references to parent in child from the generated WSDL.
Although the client can get the children list, it cannot get the parent information through the Child. Because the client is one-way now, What should I do if I want to access the parent?
Here is a solution. Add the following to the parent:Code:
Public void afterunmarshal (unmarshaller U, object parent ){
This. Parent = (parent) parent;
}
How can this problem be achieved? The reason is as follows:
The bidirectional relationship of a loop. After the relationship between one end and the other end is determined, the other end is also determined.
In the process of parsing the WSDL ing to an object (that is, unmarshal), cxf processes the parent and processes the Child contained in it. It is found that the child referenced by the parent has the afterunmarshal method, then pass your reference to child through this method, so that child also has a reference to the parent, which is done on the client. it is really a clever practice.
These functions can be implemented only when cxf is used as the client, but we can use this technology to implement this function on other clients, such as flex,. net, PHP, and so on.
One more thing
In the above example, the first access is parent, and cxf can get the information at both ends, but if you first access child, you will not get the parent.
If you add @ xmltransient to the parent, the child can get the parent information, but the getchildren of this parent may only have that child.
So let's look at the specific design. If the parent needs to access child frequently, the first is the best. If the child needs to access the parent frequently, it is obviously the second type.