Spring Data REST의 Projection 사용 시 주의사항

Spring Data REST를 이용해 서버를 구성 중, 한 엔티티에서 다른 엔티티 내용을 함께 표시할 일이 있었다.

이런 경우 @Projection 어노테이션을 이용해 일부를 제외 혹은 포함 시켜 표현해 줄 수 있는데, 내 경우에는 Spring Boot의 버전을 바꾸고 Dependency를 바꿔봐도 표현이 되지 않는 것이었다.

1
2
3
4
5
6
7
@Projection(name = "cfgkey" , types = { ConfigValueEntity.class })
public interface ConfigValueProjection {
ConfigKeyEntity getConfigKey();
String getConfigValue();
String getDescription();
Date getTimestamp();
}
1
2
3
4
5
@Projection(name = "cfgkey" , types = { ConfigKeyEntity.class })
public interface ConfigKeyProjection {
String getId();
String getFilename();
}

분명 엔티티상에 @Projection 어노테이션을 붙이는것으로 설정은 끝이었고, 다른 코드를 붙일 필요는 없어보였다.

그리고 구글을 몇 시간이나 뒤진 끝에 마침내 Spring Data REST Reference에서 찾아낸 말은 다음과 같았다.

How does Spring Data REST finds projection definitions?

  • Any @Projection interface found in the same package as your entity definitions (or one of it’s sub-packages) is registered.
  • You can manually register via RepositoryRestConfiguration.getProjectionConfiguration().addProjection(…).

In either situation, the interface with your projection MUST have the @Projection annotation.

음, 서브패키지 폴더에 넣으랜다.

넣었더니, 된다. 허헣.

현 프로젝트에서 도메인 엔티티들은 the.project.package.domain 패키지에 포함시켜뒀고, 프로젝션을 위한 인터페이스는 the.project.package.projection에 포함시켜 둔 상태였다.

여기서 the.project.package.projection 패키지를 the.project.package.domain.projection으로 이동시키자 문제가 해결된 것이다.

정말 어이없으면서도, 레퍼런스 문서에서 이 중요한 문제를 경고 표시 하나 없이 2줄로 달랑 끝냈다는게 화가나기도 한다.

여튼, 이렇게 해결되서 아래와 같이 Projection이 문제없이 잘 작동하게 됐다.

Projection 미적용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"description": "",
"timestamp": "2016-08-10T01:05:23.000+0000",
"configValue": "~~~",
"_links": {
"self": {
"href": "http://localhost:20080/api/configs/1{?projection}",
"templated": true
},
"version": {
"href": "http://localhost:20080/api/configs/1/version"
},
"software": {
"href": "http://localhost:20080/api/configs/1/software"
},
"configKey": {
"href": "http://localhost:20080/api/configs/1/configKey"
}
}
}

Projection 적용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"description": "",
"timestamp": "2016-08-10T01:05:23.000+0000",
"configKey": {
"id": "dfs.hosts.exclude",
"filename": "hdfs-site.xml"
},
"configValue": "~~~ ",
"_links": {
"self": {
"href": "http://localhost:20080/api/configs/1{?projection}",
"templated": true
},
"version": {
"href": "http://localhost:20080/api/configs/1/version"
},
"software": {
"href": "http://localhost:20080/api/configs/1/software"
},
"configKey": {
"href": "http://localhost:20080/api/configs/1/configKey"
}
}
}