如何将带有嵌入对象的对象返回给 jquery get 调用?

Posted

技术标签:

【中文标题】如何将带有嵌入对象的对象返回给 jquery get 调用?【英文标题】:How to return an object with embedded objects to a jquery get call? 【发布时间】:2021-08-18 07:05:14 【问题描述】:

我使用 jquery.get() 来调用 Spring-Boot 后端,如下所示:

    var url = "http://localhost:8080/api/v1/get_holdings?userId=1"; 
    $.get(url, function(payload,status)        
        if (status == "success") 
            $.each(payload.data, function (key,entry) 
              ...
            )
        
        else ...

在 SpringBoot 中,我创建了一个具有嵌入式模型的模型。在这种情况下,模型称为 Holding,嵌入式模型称为 Account,如下所示:

@Entity
@Table(name="holding")
public class Holding 
...
    @ManyToOne  //Many holdings to One Account
    @JoinColumn(name="account_id", nullable=false)
    private Account account;
...
//getters and setters...

对数据库的调用正确返回数据。 然后我尝试像这样将它返回给 jquery ajax 调用:

JsonResponse response = new JsonResponse();
List<Holding> holdings = holdingRepo.getUserHoldings(userId);
response.setData(holdings); //response looks correct but browser shows a 500 error.  Why?
return response;

JsonResponse 只是我用于所有响应的包装器。我已经使用了很多次,并且在许多其他调用中都可以正常工作:

    public class JsonResponse 
        private String status = null;
        private Object data = null;
        //getters and setters...

返回浏览器ok,但是浏览器报500错误。

有两种方法可以让浏览器接受数据。

    创建一个单独的模型,其中只包含我需要的数据,没有嵌入模型 使用 toString() 方法手动创建 json(很麻烦)

我尝试使用 Gson.toJson 和 JSONArray(holdings) 将 Holding 对象转换为 JSON,但这两种方法都失败了。我错过了什么?

【问题讨论】:

向我们展示您在后端看到的异常情况。 这是问题的一部分。我逐行观察调试器,一直到“返回响应”,没有显示任何错误。 1) 您没有在日志中看到任何异常吗? 2)如果在日志中没有看到异常,设置断点捕获所有异常。 不,日志中也没有异常。我在“返回响应”行设置了一个断点。我右键单击它并查看了“断点属性”,但没有看到任何名为“捕获所有异常”的内容。接下来我将尝试您的解决方案。谢谢。 * 我在“返回响应”行上设置了一个断点* - 不。我的意思是将断点设置为“任何异常”。必须有一个异常被捕获并转换为 HTTP 500 状态。 【参考方案1】:

您正在使用关系。我想会发生一个异常,如下所示:

org.hibernate.LazyInitializationException: could not initialize proxy

这可能是因为 Hibernate 尝试优化性能并且不加载关系中的对象。

那么关于SO这个问题有很多答案。

    One solution可以强制Hibernate通过初始化代理
Hibernate.initialize( entity )
    另一种方法是不向客户端发送实体,而是将它们转换为数据传输对象。如果您在事务中进行此类转换,Hibernate 将自动解析所有需要的对象,您不需要任何技巧。

【讨论】:

我在这里阅读了 DTO:thorben-janssen.com/dto-projections。 DTO 本质上与我已经在使用我创建的新类所做的事情相同,以仅保存我需要的数据。两者都需要一个新课程,这是我不应该做的额外工作。他描述的 Tuple 方法听起来更有希望,因为它不需要新的类。尽管如此,将数据库返回的实体转换为 JSON 应该是一件简单的事情。我不明白为什么这似乎不可能。无论如何,接下来我会研究你的方法#1。 再次阅读您对选项#1 的描述后,我意识到休眠正在加载所有对象。当我查看数据库返回的 Holding 对象时,它们都在那里,包括嵌入的 Account 对象。 这取决于您何时查看它。如果您在 before 事务完成之前查看它,即在标记为 transactional 的方法中,Hibernate 将解析代理对象并加载真实对象。如果您事务提交后检查它,那么您就会看到现实。如果你没有看到代理,那么我对 Hibernate 代理的假设是不正确的。 由于它仍处于开发初期,我还没有使用事务。 不可能是你不使用事务。如果没有会话,则不能使用 Hibernate 会话或实体管理器。如果您没有将方法标记为事务性的,这并不意味着它们不是。例如。 Spring Data 存储库的默认简单实现是事务性的。

以上是关于如何将带有嵌入对象的对象返回给 jquery get 调用?的主要内容,如果未能解决你的问题,请参考以下文章

如何将带有 JSON、jQuery 的复杂对象数组发布到 ASP.NET MVC 控制器?

强制将响应对象返回给 AFNetworking

如果值为空,如何将值返回给 sqldatareader?

如何从对象返回值?

Jquery 加载返回 [object 对象]

如何通过 ajax php 调用返回包含 json 对象的数组/json 对象?