[SPRING] 봄 데이터를 사용하여 널 포인터 예외 예외 Mongo 집계 가져 오기 (동적 필드)
SPRING봄 데이터를 사용하여 널 포인터 예외 예외 Mongo 집계 가져 오기 (동적 필드)
이것은 나의 Mongo Pojo도 getters와 세터 (추가되지 않음)입니다.
@CompoundIndex(name = "account_date_idx", def = "{'account' : 1, 'date' : 1}", unique = true)
@Document(collection = "agent_data_storage")
public class AgentDataStorage extends MongoKeyedEntity<String> implements Serializable {
public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
@Field
private Long account;
@Field()
private String date;
@Field
private Map<String, Double> dataPoints = new HashMap<>();
public AgentDataStorage() {
}
public AgentDataStorage(Long account) {
this.account = account;
this.date = dateFormat.format(new Date());
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public AgentDataStorage(String account) {
this.account = Long.valueOf(account);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public AgentDataStorage(Long account, Date date) {
this.account = account;
this.date = dateFormat.format(date);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public AgentDataStorage(Long account, Date date, Map<String, Double> dataPoints) {
this.account = account;
this.date = dateFormat.format(date);
this.dataPoints = dataPoints;
}
public AgentDataStorage(Long account, String date, Map<String, Double> dataPoints) {
this.account = account;
this.date = date;
this.dataPoints = dataPoints;
}
public AgentDataStorage(String account, Date date) {
this.account = Long.valueOf(account);
this.date = dateFormat.format(date);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public AgentDataStorage(String account, String date) {
this.account = Long.valueOf(account);
this.date = date;
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public Long getAccount() {
return account;
}
public void setAccount(Long account) {
this.account = account;
}
public Date getDate() throws ParseException {
return dateFormat.parse(this.date);
}
public void setDate(Date date) {
this.date = dateFormat.format(date);
}
public Map<String, Double> getDataPoints() {
return dataPoints;
}
public void setDataPoints(Map<String, Double> dataPoints) {
this.dataPoints = dataPoints;
}
public void updateDataPoint(AgentDataPoints agentDataPoints, Double value) {
this.dataPoints.put(String.valueOf(agentDataPoints), value);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("AgentDataStorage{");
sb.append("account=").append(account);
sb.append(", date=").append(date);
sb.append(", dataPoints=").append(dataPoints);
sb.append('}');
return sb.toString();
}
}
집계를 시도하는 동안 null 포인터 예외가 발생하는 동안 아래는 테스트 케이스입니다.
@Test
public void aggregationTest() {
Long account = 12121l;
String startDay = "2016-01-01";
String endDay = "2016-01-03";
Aggregation aggregation = Aggregation
.newAggregation(match(Criteria.where("account").is(account).and("date")
.gte(startDay).lte(endDay)),
group("account").sum("dataPoints.TOTAL_BUS_COMMISSION").as("total"));
AggregationResults<AggregationResult> results = mongoTemplate.aggregate(aggregation,
AgentDataStorage.class, AggregationResult.class);
}
내 AggregationResult 클래스는 -
public class AggregationResult {
private Long _id;
private Double total;
public Long get_id() {
return _id;
}
public void set_id(Long _id) {
this._id = _id;
}
public Double getTotal() {
return total;
}
public void setTotal(Double total) {
this.total = total;
}
}
다음은 스택 추적 오류입니다.
java.lang.NullPointerException
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:233)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:214)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:210)
at org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext.getReferenceFor(TypeBasedAggregationOperationContext.java:96)
at org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext.getReference(TypeBasedAggregationOperationContext.java:91)
at org.springframework.data.mongodb.core.aggregation.GroupOperation$Operation.getValue(GroupOperation.java:434)
at org.springframework.data.mongodb.core.aggregation.GroupOperation$Operation.toDBObject(GroupOperation.java:416)
at org.springframework.data.mongodb.core.aggregation.GroupOperation.toDBObject(GroupOperation.java:361)
at org.springframework.data.mongodb.core.aggregation.Aggregation.toDbObject(Aggregation.java:331)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1500)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1435)
at psl.service.core.agentanalytics.internal.AgentAnalyticsServiceTest.aggregationTest(AgentAnalyticsServiceTest.java:132)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:72)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:81)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:216)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:82)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:67)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:162)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
또한 내부 스프링 용기를 디버깅하려고 시도했는데, DoubleMapping의 경우 AbstractMappingContext.java 내부에서 null을 던지지 만 왜 그런 일이 일어나는지 이해할 수는 없습니다. mongo 같은 쿼리가 mongo 콘솔에서 작동합니다.
db.getCollection('agent_data_storage').aggregate([
{ "$match" : { "account" : 12121 , "date" : { "$gte" : "2016-01-01" , "$lte" : "2016-01-03"}}}
, { "$group" : { "_id" : "$account" , "total" : { "$sum" : "$dataPoints.TOTAL_BUS_COMMISSION"}}}])
위 쿼리의 결과는 다음과 같습니다.
{
"_id" : NumberLong(12121),
"total" : 402.0
}
모든 종류의 도움말에 감사드립니다.
AgentDataStorage-
{
"_id" : ObjectId("586233e3fb94f6f5640196cf"),
"account" : NumberLong(12121),
"date" : "2016-01-01",
"dataPoints" : {
"TOTAL_BUS_COMMISSION" : 0.0
}
}
해결법
-
==============================
1.기본적으로 입력 유형 (AgentDataStorage)의 속성 참조를 필드 이름으로 변환하려고하는 집계의 유형화 된 집계 변형을 사용하지 말고 dataPoints.TOTAL_BUS_COMMISSION의 경우 속성 참조를 찾지 못하면 실패합니다.
기본적으로 입력 유형 (AgentDataStorage)의 속성 참조를 필드 이름으로 변환하려고하는 집계의 유형화 된 집계 변형을 사용하지 말고 dataPoints.TOTAL_BUS_COMMISSION의 경우 속성 참조를 찾지 못하면 실패합니다.
용도
AggregationResults<AggregationResult> results = mongoTemplate.aggregate(aggregation, "agent_data_storage", AggregationResult.class);
from https://stackoverflow.com/questions/41346329/getting-null-pointer-exception-mongo-aggregation-using-spring-datadynamic-field by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Junit 테스트에서 종속성을 주입 할 수 없음 (0) | 2019.02.28 |
---|---|
[SPRING] soap spring ws - <faultcode>를 사용자 정의하는 방법 soapenv : 서버 </ faultcode>에서 <faultcode> 일부 오류 code.eg (숫자) </ faultcode> (0) | 2019.02.28 |
[SPRING] POST 요청에서 XML을 가져 와서 서블릿 필터에서 수정하는 방법? (1) | 2019.02.28 |
[SPRING] Vaadin : 데이터를 변경하기위한 UI 참조 얻기 (0) | 2019.02.28 |
[SPRING] 하나의 상태 전이에서 다른 상태 전이 junit으로 플로우 스코프 변수를 가져올 수 없다. (0) | 2019.02.28 |