我正在研究一个由hibernate映射的多对多关系的项目。使用Spring 4.0+(也尝试使用spring 3.0+),Hibernate 4.0+,Jackson 2.0+。 我面临的问题是,在映射多个到多个时,我得到一个错误,如下所示:
编辑:我在关系(Set和Set)的两边使用@JsonIdentityInfo(截至今天),下面是错误。我还在下面的代码中添加了注释。
2016-02-05 12:41:51,984 DEBUG http-bio-8080-exec-2 org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver - Resolving exception from handler [com.techmust.inventory.items.ItemGroupDataProcessor@143dd30]: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError) (through reference chain: org.hibernate.collection.internal.PersistentSet[0]->com.techmust.inventory.items.ItemGroupData["m_oGroupItems"]->org.hibernate.collection.internal.PersistentSet[0]->com.techmust.inventory.items.ItemData["m_oItemGroups"]->org.hibernate.collection.internal.PersistentSet[0]->com.techmust.inventory.items.ItemData["m_oCreatedBy"]->com.techmust.usermanagement.userinfo.UserInformationData["m_oRole"]->com.techmust.usermanagement.role.RoleData["m_oActions"]->org.hibernate.collection.internal.PersistentSet[25]->com.techmust.usermanagement.action.ActionData["m_strActionTarget"])
2016-02-05 12:41:52,000 WARN http-bio-8080-exec-2 org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Handling of [org.springframework.http.converter.HttpMessageNotWritableException] resulted in Exception
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:466)
at org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.handleHttpMessageNotWritable(DefaultHandlerExceptionResolver.java:313)
at org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.doResolveException(DefaultHandlerExceptionResolver.java:117)
at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:136)
at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:987)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:811)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:669)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:585)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:662)
2016-02-05 12:41:52,000 DEBUG http-bio-8080-exec-2 org.springframework.web.servlet.DispatcherServlet - Could not complete request
到目前为止我尝试了什么: 1)提到stackoverflow上的大多数帖子,其他文章/博客。 2)还使用了@JsonIgnore,@ JsonManagedReference,@ JsonBackReference打破了一对多和多对一的循环依赖错误,这对多对多工作正常我试过这个@JsonIdentityInfo但仍然显示循环依赖错误。
OwnItemDataProcessor.java
@Controller
public class OwnItemDataProcessor extends ItemDataProcessor
{
@RequestMapping(value="/ownItemDataCreate", method = RequestMethod.POST, headers = {"Content-type=application/json"})
@ResponseBody
public GenericResponse create(@RequestBody ItemData oItemData) throws Exception
{
m_oLogger.info ("create");
m_oLogger.debug ("create - oItemData - m_strArticleNumber [IN] : " + oItemData.getM_strArticleNumber());
ItemDataResponse oItemDataResponse = new ItemDataResponse ();
VendorItemData oVendorItemData = new VendorItemData ();
try
{
oVendorItemData.getM_oVendorData().setM_nClientId(getDefaultVendorId ());
oItemDataResponse = (ItemDataResponse) super.create(oItemData);
oVendorItemData.getM_oItemData().setM_nItemId(oItemDataResponse.m_arrItems.get(0).getM_nItemId());
oItemDataResponse.m_bSuccess = oVendorItemData.saveObject();
}
catch (Exception oException)
{
m_oLogger.error ("create - oException : " + oException);
throw oException;
}
m_oLogger.debug ("create - oItemDataResponse.m_bSuccess [OUT] : " + oItemDataResponse.m_bSuccess);
return oItemDataResponse;
}
}
UserInformationData.java
public String getActionsAsXML ()
{
m_oLogger.info ("getActionsAsXML");
String strXML = "<root>";
PersistentSet oActionSet = (PersistentSet) (this.getm_oRole ().getm_oActions ());
strXML += getActionsAsXML (oActionSet);
strXML += "</root>";
m_oLogger.debug ( "getActionsAsXML - strXML [OUT] : " + strXML);
return strXML;
}
ItemDataResponse.java
public class ItemDataResponse extends GenericResponse
{
private static final long serialVersionUID = 1L;
public ArrayList<ItemData> m_arrItems ;
public ArrayList<VendorItemData> m_arrVendorItems ;
public long m_nRowCount;
public ItemDataResponse ()
{
m_arrItems = new ArrayList<ItemData> ();
m_arrVendorItems = new ArrayList<VendorItemData> ();
m_nRowCount=0;
}
}
ItemData.java
public class ItemData extends GenericData
{
private int m_nItemId;
private UserInformationData m_oCreatedBy;
private ApplicableTax m_oApplicableTax;
private ApplicableTax m_oTaxWithCForm;
private UserInformationData m_oUserCredentialsData;
public ItemGroupData [] m_arrItemGroups;
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="m_nItemId")
private Set<ItemGroupData> m_oItemGroups;
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="m_nItemId")
private Set<ChildItemData> m_oChildItems;
public ChildItemData [] m_arrChildItems;
private ItemCategoryData m_oItemCategoryData;
// Getters/Setters
}
ItemGroupData.Java
public class ItemGroupData extends GenericData
{
public int m_nItemGroupId;
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="m_nItemGroupId")
private Set<ItemData> m_oGroupItems;
public ItemData [] m_arrGroupItems;
//Getters/Setters
}
Items.hbm.xml
<hibernate-mapping package="com.techmust.inventory.items">
<class name="ItemData" table="tac01_items" discriminator-value="items">
<id name="m_nItemId" type="int" column="ac01_item_id">
<generator class="native"></generator>
</id>
<many-to-one name="m_oCreatedBy" class="com.techmust.usermanagement.userinfo.UserInformationData" lazy="false">
<column name="ac01_Created_by" />
</many-to-one>
<many-to-one name="m_oApplicableTax" lazy="false" column="ac01_applicable_tax" class="com.techmust.inventory.tax.ApplicableTax"></many-to-one>
<many-to-one name="m_oTaxWithCForm" lazy="false" column="ac01_TaxWithCForm" class="com.techmust.inventory.tax.ApplicableTax"></many-to-one>
<set name="m_oItemGroups" lazy="false" table="tac36_group_items" cascade="all-delete-orphan" inverse="true">
<key column="ac36_item_id"/>
<many-to-many lazy="false" column="ac36_group_id"
class="com.techmust.inventory.items.ItemGroupData"/>
</set>
<set name="m_oChildItems" lazy="false" table="tac51_child_items" cascade="all-delete-orphan">
<key column="ac51_parent_item_id"/>
<one-to-many class="com.techmust.inventory.items.ChildItemData"/>
</set>
<many-to-one name="m_oItemCategoryData" lazy="false" column="ac01_ItemCategory" class="com.techmust.inventory.items.ItemCategoryData" not-null="true"></many-to-one>
<set name="m_oItemImage" lazy="false" table="tac65_item_images" cascade="all-delete-orphan">
<key column="ac01_item_id"/>
<one-to-many class="com.techmust.inventory.items.ItemImagesData"/>
</set>
</class>
</hibernate-mapping>
ItemGroup.hbm.xml
<hibernate-mapping package="com.techmust.inventory.items">
<class name="ItemGroupData" table="tac35_item_group">
<id name="m_nItemGroupId" column="ac35_id" type="int">
<generator class="native"></generator>
</id>
<many-to-one name="m_oCreatedBy" class="com.techmust.usermanagement.userinfo.UserInformationData" lazy="false">
<column name="ac35_created_by"/>
</many-to-one>
<set name="m_oGroupItems" lazy="false" table="tac36_group_items">
<key column="ac36_group_id"/>
<many-to-many lazy="false" column="ac36_item_id"
class="com.techmust.inventory.items.ItemData"/>
</set>
</class>
</hibernate-mapping>
有人可以帮助我做错了什么,以及与多对多关系合作的正确方法。