【问题标题】:How to set variable in Java projection?如何在 Java 投影中设置变量?
【发布时间】:2022-01-22 15:55:50
【问题描述】:

我的 Java (Spring Boot) 应用程序中有以下投影:

public interface DemoProjection {
    UUID getUuid();
    String getName();
    String getSurname();

    String getLabel();
    void setLabel(String label);

我想在我的服务中设置这个 label 字段:

public DemoProjection findAByUuid(UUID uuid) {
        // returns a single record
        final DemoProjection demo =  demoRepository.findAByUuid(uuid);
        final String label = String.format(
                "Name: %s%nSurnamame Surname: %s",
                demo.geteName(),
                demo.getSurname());

        // ! this line throws error
        demo.setLabel(label);
        return demo;
    }

demo.setLabel(label); 抛出错误:“无法设置投影 TupleBackedMap 无法修改。”

那么,如何在投影中设置label 字段?

【问题讨论】:

  • demoRepository.findAll() 返回什么?
  • 它当然会返回投影
  • findAll() 似乎返回了超过 1 个对象,它被映射到 touples 而不仅仅是 1 个对象。这意味着您不能像使用单个对象那样直接访问字段。您应该重新考虑您的命名约定。
  • 不,它只返回DemoProjection 类型中的一个元素。对不起,我打错了它的名字。
  • 设置断点并停止setLabel()上的代码。您将看到您的对象可能看起来不同。可能不是主对象本身,而是标签属性。

标签: java spring spring-boot projection


【解决方案1】:

你实际上不能这样做。 Spring Data 使用代理和 AOP 将查询结果绑定到您的投影界面,并且由于它是一个界面,因此您无法以神奇的方式更改它。我建议创建一个模型/dto 并在那里映射您的投影值:

public class DemoDto {
  private String uuid;
  private String name;
  private String surname;
  
  //getters and setters ommited for brevity
}

您可以使用所需的值创建一个 DemoDto 对象。

或者,您可以使用投影类而不是投影接口。查看 spring 文档以了解如何做到这一点:)

【讨论】:

  • 我不确定是否可以使用投影类而不是接口。那么,发布一个示例怎么样?
【解决方案2】:

只需在您的 DemoProjection 界面中创建一个默认方法以返回您希望的格式的 getLabel:

public interface DemoProjection {
  UUID getUuid();
  String getName();
  String getSurname();

  default String getLabel() {
      return String.format(
            "Name: %s%nSurnamame Surname: %s",
            geteName(),
            getSurname());
  }
}

这是必需的,因为您无法在 JPA 创建 Projection 后对其进行设置,但由于您只需要格式化,因此无需设置任何内容 - 默认方法可以解决问题。

【讨论】:

  • 感谢您的帮助。实际上我正是使用了这种方法,但我想将这种逻辑转移到服务中。在这种情况下,我该如何解决这个问题?
  • 然后将 getLabel 方法移动到接受 Projection 作为参数并返回格式化标签的服务中。
  • 请提供任何示例代码?如果更好的方法,我可能会使用您的方法并选择您的答案
  • 我们不是来为您编写代码的,您应该提供代码,说明您尝试过的内容以及它对您遇到的每一个问题都不起作用的原因。然后我们会很高兴地纠正。像将方法移动到另一个类这样简单的请求,你只是在偷懒
猜你喜欢
  • 1970-01-01
  • 2018-08-31
  • 2018-08-06
  • 2018-08-08
  • 2011-12-08
  • 1970-01-01
  • 2019-03-17
  • 1970-01-01
  • 2012-05-15
相关资源
最近更新 更多