[SPRING] 복합 기본 키로 봄 데이터 휴식
SPRING복합 기본 키로 봄 데이터 휴식
나는 봄 데이터 휴식을 사용한다. 그러나 엔티티가 복합 기본 키를 가지고있을 때 기본 키를 제공하여 엔티티를 얻는 방법을 모른다.
강 클래스 :
@Entity
public class River {
private RiverPK id;
private Double length;
private Timestamp date;
private String comment;
@Basic
@Column(name = "length")
public Double getLength() {
return length;
}
public void setLength(Double length) {
this.length = length;
}
@Basic
@Column(name = "date")
public Timestamp getDate() {
return date;
}
public void setDate(Timestamp date) {
this.date = date;
}
@Basic
@Column(name = "comment")
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
@Id
public RiverPK getId() {
return id;
}
public void setId(RiverPK id) {
this.id = id;
}
}
RiverPK 클래스 :
@Embeddable
public class RiverPK implements Serializable {
private String name;
private int upcode;
private int downcode;
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "upcode")
public int getUpcode() {
return upcode;
}
public void setUpcode(int upcode) {
this.upcode = upcode;
}
@Column(name = "downcode")
public int getDowncode() {
return downcode;
}
public void setDowncode(int downcode) {
this.downcode = downcode;
}
}
RiverDAO 클래스 :
@RepositoryRestResource(path = "river")
public interface RiverDAO extends JpaRepository<River, RiverPK> {
}
그런 다음 http : // localhost : 8080 / river /을 호출하여 강 데이터를 가져올 수 있으며 http : // localhost : 8080 / river / {river json} 콜 포스트를 통해 db에 새로운 엔티티를 만들 수 있습니다.
강 json은 다음과 같습니다.
id": {
"name": "1",
"upcode": 2,
"downcode": 3
},
"length": 4.4,
"date": 1493740800000,
"comment": "6"
}
spring data rest doc에서는 get localhost : 8080 / river / 1 (기본 키)을 호출하여 기본 키가 1 인 엔터티를 가져올 수 있어야합니다. 엔터티에 기본 키가 하나 뿐인 경우에도 작동 할 수 있습니다. 하지만 제 엔터티 리버에는 RiverPK와 같은 복합 기본 키가 있습니다. get localhost : 8080 / river / {name = '1', upcode = 2, downcode = 3}을 호출하면 "형식 [java.lang.String]에서 유형 [com]으로 변환 할 수있는 변환기를 찾을 수 없습니다 .example.db.entity.RiverPK] ", 즉 스프링 사용 {name = '1', upcode = 2, downcode = 3}을 문자열로 나타내지 만 RiverPK 유형은 아닙니다.
질문은 복합 기본 키를 다른 일반 엔티티로 사용하여 get \ put \ delete를 호출하는 방법입니다.
해결법
-
==============================
1.살펴볼 수있는 jira 문제가 있습니다. https://jira.spring.io/browse/DATAREST-598
살펴볼 수있는 jira 문제가 있습니다. https://jira.spring.io/browse/DATAREST-598
이 의견은 특히 당신에게 흥미로울 수 있습니다.
https://jira.spring.io/browse/DATAREST-598?focusedCommentId=117740&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-117740
샘플 프로젝트에 대한 github 링크도 있습니다. BackendIdConverter를 사용하여 복합 키를 문자열과 역으로 변환합니다. 따라서 트릭은 복합 ID를 경로 세그먼트로 사용할 수있는 문자열로 변환하는 것입니다.
이 대답은 당신에게도 흥미로울 것입니다. https://stackoverflow.com/a/31830586/5371736
-
==============================
2.composite id를 가진 엔티티에 대한 HATEOAS 링크 생성을 커스터마이징 한 결과, 훨씬 일반적인 솔루션을 발견했습니다.
composite id를 가진 엔티티에 대한 HATEOAS 링크 생성을 커스터마이징 한 결과, 훨씬 일반적인 솔루션을 발견했습니다.
먼저 SpringUtil을 생성하여 Spring에서 Bean을 가져온다.
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class SpringUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if(SpringUtil.applicationContext == null) { SpringUtil.applicationContext = applicationContext; } } public static ApplicationContext getApplicationContext() { return applicationContext; } public static Object getBean(String name){ return getApplicationContext().getBean(name); } public static <T> T getBean(Class<T> clazz){ return getApplicationContext().getBean(clazz); } public static <T> T getBean(String name,Class<T> clazz){ return getApplicationContext().getBean(name, clazz); } }
그런 다음 BackendIdConverter를 구현하십시오.
import com.alibaba.fastjson.JSON; import com.example.SpringUtil; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.rest.webmvc.spi.BackendIdConverter; import org.springframework.stereotype.Component; import javax.persistence.EmbeddedId; import javax.persistence.Id; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.lang.reflect.Method; import java.net.URLDecoder; import java.net.URLEncoder; @Component public class CustomBackendIdConverter implements BackendIdConverter { @Override public boolean supports(Class<?> delimiter) { return true; } @Override public Serializable fromRequestId(String id, Class<?> entityType) { if (id == null) { return null; } //first decode url string if (!id.contains(" ") && id.toUpperCase().contains("%7B")) { try { id = URLDecoder.decode(id, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } //deserialize json string to ID object Object idObject = null; for (Method method : entityType.getDeclaredMethods()) { if (method.isAnnotationPresent(Id.class) || method.isAnnotationPresent(EmbeddedId.class)) { idObject = JSON.parseObject(id, method.getGenericReturnType()); break; } } //get dao class from spring Object daoClass = null; try { daoClass = SpringUtil.getBean(Class.forName("com.example.db.dao." + entityType.getSimpleName() + "DAO")); } catch (ClassNotFoundException e) { e.printStackTrace(); } //get the entity with given primary key JpaRepository simpleJpaRepository = (JpaRepository) daoClass; Object entity = simpleJpaRepository.findOne((Serializable) idObject); return (Serializable) entity; } @Override public String toRequestId(Serializable id, Class<?> entityType) { if (id == null) { return null; } String jsonString = JSON.toJSONString(id); String encodedString = ""; try { encodedString = URLEncoder.encode(jsonString, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return encodedString; } }
그 후. 당신이 원하는 것을 할 수 있습니다.
아래 샘플이 있습니다.
from https://stackoverflow.com/questions/43763250/spring-data-rest-with-composite-primary-key by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring 보안 jdbcAuthentication은 기본 롤 처리와 함께 작동하지 않습니다. (0) | 2019.01.23 |
---|---|
[SPRING] WS SoapFault에 세부 정보 추가하기 : 내 사용자 지정 ExceptionResolver가 사용되지 않았습니다. (0) | 2019.01.23 |
[SPRING] Spring 트랜잭션 관리자와 다중 쓰레드 (0) | 2019.01.22 |
[SPRING] AspectJ와의 Spring / @Transactional은 완전히 무시된다. (0) | 2019.01.22 |
[SPRING] Spring MVC를 사용하여 <form : input type = "file"> 값 유지하기 (0) | 2019.01.22 |