多对多Hibernate Spring配置,错误:HTTPMessageNotWritableException:无法编写JSON

时间:2016-02-03 10:02:59

标签: java spring hibernate spring-mvc jackson

我正在研究一个由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>

有人可以帮助我做错了什么,以及与多对多关系合作的正确方法。

0 个答案:

没有答案