복붙노트

[SPRING] Spring Data Cassandra를 사용하여 java.util.Date 값을 Cassandra 날짜 유형 컬럼에 삽입하는 방법?

SPRING

Spring Data Cassandra를 사용하여 java.util.Date 값을 Cassandra 날짜 유형 컬럼에 삽입하는 방법?

다음과 같이 날짜 유형 열이있는 cassandra 테이블이 있습니다.

create table people
(
   id int primary key, 
   name text, 
   email text, 
   dob date
);

나는 Spring Boot 1.5.2 + Spring Data Cassandra Starter를 사용하고있다.

@Table("people")
public class Person {
    @PrimaryKey
    Integer id;
    private String name;
    private String email;
    private java.util.Date dob;
    //setters and getters
}

public interface PersonRepository extends CrudRepository<Person, Integer>{

}

나는 다음과 같이 새로운 Person을 삽입한다 :

personRepository.save(new Person(1, "Siva","siva@gmail.com", new java.util.Date()));

다음 오류가 발생합니다.

Caused by: com.datastax.driver.core.exceptions.InvalidQueryException: Expected 4 byte long for date (8)
    at com.datastax.driver.core.Responses$Error.asException(Responses.java:136) ~[cassandra-driver-core-3.1.4.jar:na]
    at com.datastax.driver.core.DefaultResultSetFuture.onSet(DefaultResultSetFuture.java:179) ~[cassandra-driver-core-3.1.4.jar:na]
    at com.datastax.driver.core.RequestHandler.setFinalResult(RequestHandler.java:177) ~[cassandra-driver-core-3.1.4.jar:na]
    at com.datastax.driver.core.RequestHandler.access$2500(RequestHandler.java:46) ~[cassandra-driver-core-3.1.4.jar:na]

하지만 타임 스탬프에 dob 컬럼 타입을 만들면 잘 동작합니다. 날짜 유형 열을 가질 수 있고 java.util.Date 유형 특성을 사용할 수 있습니까?

P.s : java.sql.Date를 사용하더라도 동일한 오류가 발생합니다.

해결법

  1. ==============================

    1.com.datastax.driver.core.LocalDate를 사용하십시오.

    com.datastax.driver.core.LocalDate를 사용하십시오.

    이러한 메소드를 사용하여 java.util.Date에서 LocalDate를 가져올 수 있습니다.

    또는 Cassandra 날짜 유형에 java.util.Date를 삽입 할 수있는 자체 코덱을 만들 수 있습니다.

    다음과 같이 시작할 수 있습니다.

    public class DateCodec extends TypeCodec<Date> {
    
        private final TypeCodec<LocalDate> innerCodec;
    
        public DateCodec(TypeCodec<LocalDate> codec, Class<Date> javaClass) {
            super(codec.getCqlType(), javaClass);
            innerCodec = codec;
        }
    
        @Override
        public ByteBuffer serialize(Date value, ProtocolVersion protocolVersion) throws InvalidTypeException {
            return innerCodec.serialize(LocalDate.fromMillisSinceEpoch(value.getTime()), protocolVersion);
        }
    
        @Override
        public Date deserialize(ByteBuffer bytes, ProtocolVersion protocolVersion) throws InvalidTypeException {
            return new Date(innerCodec.deserialize(bytes, protocolVersion).getMillisSinceEpoch());
        }
    
        @Override
        public Date parse(String value) throws InvalidTypeException {
            return new Date(innerCodec.parse(value).getMillisSinceEpoch());
        }
    
        @Override
        public String format(Date value) throws InvalidTypeException {
            return value.toString();
        }
    
    }
    

    연결을 만들 때 등록해야합니다.

    CodecRegistry codecRegistry = new CodecRegistry();
    codecRegistry.register(new DateCodec(TypeCodec.date(), Date.class));
    Cluster.builder().withCodecRegistry(codecRegistry).build();
    

    추가 정보 : http://docs.datastax.com/en/developer/java-driver/3.1/manual/custom_codecs/

  2. from https://stackoverflow.com/questions/43064133/how-to-insert-java-util-date-values-into-cassandra-date-type-column-using-spring by cc-by-sa and MIT license