如果POJO的键是复合的,则Spring Data Cassandra不映射JSON请求

时间:2017-12-15 09:16:08

标签: spring-boot spring-data spring-data-cassandra spring-boot-test

我正在尝试将请求保存到Data Stax-Cassandra。 组件: EventController:@RestEndPoint OneKeyClass:对于复杂键(具有多列) 我正在使用标准Spring存储库模型来保存和获取数据。

Gradle:
plugins {
    id "org.springframework.boot" version "1.5.3.RELEASE"
}

apply plugin: 'java'

jar {
    baseName = 'sample-boot-with-cassandra'
    version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-cassandra')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.kafka:spring-kafka')
        compile('org.springframework.kafka:spring-kafka-test')


    testCompile('org.springframework.boot:spring-boot-starter-test')
}

控制器:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.company.employee.model.Event;
import com.company.employee.service.EventService;

@RestController
@RequestMapping("/event")
public class EventController {

    @Autowired
    private EventService eventService;

    @PostMapping
    public ResponseEntity<Event> saveEvent(@RequestBody Event event){
        return new ResponseEntity<Event>(eventService.saveEvent(event), HttpStatus.CREATED);
    }
}

EventServiceImpl

package com.company.employee.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.company.employee.model.Event;
import com.company.employee.model.LoginEvent;
import com.company.employee.repository.EventRepository;
import com.company.employee.repository.LoginEventRepository;

@Service
public class EventServiceImpl implements EventService {
    private EventRepository eventRepository;

    private LoginEventRepository loginEventRepository;
    private Logger logger=LoggerFactory.getLogger(EmployeeServiceImpl.class);

    @Autowired
     public EventServiceImpl(EventRepository eventRepository,LoginEventRepository loginEventRepository) {
         this.eventRepository=eventRepository;
         this.loginEventRepository=loginEventRepository;
     }

    @Override
    public Event saveEvent(Event event) {
        logger.info("saving event"+event.toString());
        return eventRepository.save(event);
    }

    @Override
    public LoginEvent saveEvent(LoginEvent event) {
        return loginEventRepository.save(event);
    }

}

存储库:

package com.company.employee.repository;

import org.springframework.data.cassandra.repository.CassandraRepository;

import com.company.employee.model.Event;

public interface EventRepository extends CassandraRepository<Event> {

}

事件:

package com.company.employee.model;

import org.springframework.data.cassandra.mapping.Column;
import org.springframework.data.cassandra.mapping.PrimaryKey;
import org.springframework.data.cassandra.mapping.Table;

@Table(value="event")
public class Event {

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Event [eventKey=").append(eventKey).append(", transactionstatus=").append(transactionstatus)
                .append("]");
        return builder.toString();
    }

    @PrimaryKey
    private EventKey eventKey;

    public EventKey getEventKey() {
        return eventKey;
    }

    public void setEventKey(EventKey eventKey) {
        this.eventKey = eventKey;
    }

    public String getTransactionstatus() {
        return transactionstatus;
    }

    public void setTransactionstatus(String transactionstatus) {
        this.transactionstatus = transactionstatus;
    }

    @Column(value="transactionstatus")
    private String transactionstatus;
}

EventKey     package com.company.employee.model;

import java.io.Serializable;

import org.springframework.cassandra.core.Ordering;
import org.springframework.cassandra.core.PrimaryKeyType;
import org.springframework.data.cassandra.mapping.PrimaryKeyClass;
import org.springframework.data.cassandra.mapping.PrimaryKeyColumn;

@PrimaryKeyClass
public class EventKey implements Serializable {

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("EventKey [eventsource=").append(eventsource).append(", eventid=").append(eventid)
                .append(", eventstate=").append(eventstate).append("]");
        return builder.toString();
    }
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + eventid;
        result = prime * result + ((eventsource == null) ? 0 : eventsource.hashCode());
        result = prime * result + ((eventstate == null) ? 0 : eventstate.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        EventKey other = (EventKey) obj;
        if (eventid != other.eventid)
            return false;
        if (eventsource == null) {
            if (other.eventsource != null)
                return false;
        } else if (!eventsource.equals(other.eventsource))
            return false;
        if (eventstate == null) {
            if (other.eventstate != null)
                return false;
        } else if (!eventstate.equals(other.eventstate))
            return false;
        return true;
    }
    public String getEventsource() {
        return eventsource;
    }
    public void setEventsource(String eventsource) {
        this.eventsource = eventsource;
    }
    public EventKey(String eventsource, int eventid, String eventstate) {
        super();
        this.eventsource = eventsource;
        this.eventid = eventid;
        this.eventstate = eventstate;
    }
    public int getEventid() {
        return eventid;
    }
    public void setEventid(int eventid) {
        this.eventid = eventid;
    }
    public String getEventstate() {
        return eventstate;
    }
    public void setEventstate(String eventstate) {
        this.eventstate = eventstate;
    }
    @PrimaryKeyColumn(name="eventsource",ordinal=0,type=PrimaryKeyType.PARTITIONED)
    private String eventsource;

    @PrimaryKeyColumn(name="eventid",ordinal=1,type=PrimaryKeyType.CLUSTERED,ordering=Ordering.ASCENDING)
    private int eventid;

    @PrimaryKeyColumn(name="eventstate",ordinal=2,type=PrimaryKeyType.CLUSTERED,ordering=Ordering.ASCENDING)
    private String eventstate;


}

错误: java.lang.IllegalArgumentException:目标bean不能为null!

保存eventEvent [ eventKey = null ,transactionstatus =成功]

传入有效负载:

{
  "eventsource" : "terminal",
  "eventid": "23232",
  "eventstate" : "CI",
  "transactionstatus" : "success"
}

我跟着 https://docs.spring.io/spring-data/cassandra/docs/1.0.2.RELEASE/reference/html/cassandra.core.html

提前感谢您寻求帮助。

1 个答案:

答案 0 :(得分:1)

JSON有效负载与您的对象结构不匹配。您的JSON表示应该匹配:

{
  "eventKey": {
    "eventsource" : "terminal",
    "eventid": "23232",
    "eventstate" : "CI"
  },
  "transactionstatus" : "success"
}

或者,您可以将EventKey内联到Event或使用两种不同的数据结构,一种用于API,另一种用于在Cassandra中存储和查询数据。尽管使用相同的类型通过您的API表示您的数据并且以其持久形式使用更少的代码并且没有映射,但IMHO拆分职责是保持事物分离的更好选择。