【问题标题】:How to return an object with embedded objects to a jquery get call?如何将带有嵌入对象的对象返回给 jquery get 调用?
【发布时间】: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错误。

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

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

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

【问题讨论】:

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

标签: javascript java jquery ajax spring-boot


【解决方案1】:

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

org.hibernate.LazyInitializationException: could not initialize proxy

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

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

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

【讨论】:

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