嵌入式实体的Spring Data Rest投影

时间:2015-05-15 13:46:52

标签: java spring spring-data-rest

假设我有以下实体:

char * first_newline = strchr(str, '\n');
if (first_newline)
    *first_newline = '\0'

我正在尝试创建以下JSON表示,所以当我使用@Entity public class Registration { @ManyToOne private Student student; //getters, setters } @Entity public class Student { private String id; private String userName; private String name; private String surname; //getters, setters } @Projection(name="minimal", types = {Registration.class, Student.class}) public interface RegistrationProjection { String getUserName(); Student getStudent(); } 时,我不需要所有用户数据出现:

http://localhost:8080/api/registrations?projection=minimal

然而,我创建的Projection我得到一个异常(它没有getUserName()语句。显然我已经以错误的方式定义了接口......但这是做这样的事情的正确方法吗?

编辑:例外情况如下

{
  "_links": {
    "self": {
      "href": "http://localhost:8080/api/registrations{?page,size,sort,projection}",
    }
  },
  "_embedded": {
    "registrations": [
      {
        "student": {
          "userName": "user1"
        }
      }
    ],
    "_links": {
      "self": {
        "href": "http://localhost:8080/api/registrations/1{?projection}",
      }
    }
  }
}

1 个答案:

答案 0 :(得分:9)

异常说userName不是Registration实体的成员。这就是它失败的原因。但我想你已经明白了。

首先,如果您只想公开Registration的预测,首先应更改以下行:

@Projection(name="minimal", types = {Registration.class, Student.class})

通过设置types = {Registration.class, Student.class},您要求Spring Data Rest在Registration.classStudent.class上应用投影。这可能会导致一些问题,因为根据类型,您不应该使用相同的成员/方法。实际上types必须共享一个共同的祖先。

否则对于主要问题你应该尝试virtual projections以下的事情(我没试过你的样本,但它应该有用,我希望):

@Projection(name="minimal", types = {Registration.class})
public interface RegistrationProjection {

    @Value("#{target.getStudent().getUserName()}")
    String getUserName();
}

我不知道您是否熟悉SPeL,但之前的代码只是创建getUserName this.getStudent().getUserName(),因为target绑定在实例对象上(请参阅文档)。