如何使用spring数据cassandra创建一组用户定义的类型?

时间:2018-04-16 00:24:34

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

我使用Spring Data Cassandra 1.5.8.RELEASE连接我的cassandra db 3.11.2。

我尝试使用Set作为列字段创建@Table pojo,但它抛出以下错误:
未找到用户定义的类型,以及
其他一些cassandra映射异常。

有人可以帮我数据建模一个'Employee'表,它有一个代表一组Department UDT的列吗? (使用spring boot,spring data cassandra 1.5.8+和Apache cassandra 3.11.2 +)

1 个答案:

答案 0 :(得分:1)

首先,我的主要问题是CassandraConfig.java,我不一定要覆盖某些方法,因为默认实现本身就足够了。

在这里,我发布了我的完整解决方案,以帮助那些第一次尝试这个用例的人。

项目文件夹结构:

enter image description here

第1步:创建cassandra数据模型:

CREATE KEYSPACE cassandra_sample
WITH replication = {'class':'SimpleStrategy', 'replication_factor' : 3};

CREATE TYPE dept_details (
    dept_name text,
    dept_address text
);

CREATE TABLE emp_details (
    emp_id int PRIMARY KEY,
    emp_name text,
    emp_designation text,
    dept_info set<frozen<dept_details>>
);

第2步:pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.cassandra.sample</groupId>
    <artifactId>spring-data-cassandra-sample</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringDataCassandraSample</name>
    <description>SpringDataCassandraSample</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-cassandra</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <properties>
        <java.version>1.8</java.version>
    </properties>
</project>

第3步:Application.java

package com;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

第4步:application.properties

# ===============================
# == DATA SOURCE
# ===============================
spring.data.cassandra.keyspace-name=cassandra_sample
spring.data.cassandra.contact-points=localhost
spring.data.cassandra.port=9042
spring.data.cassandra.schema-action=create_if_not_exists

第5步:CassandraConfig.java

package com.cassandra.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.java.AbstractCassandraConfiguration;

/**
 * Created by jt on 10/6/17.
 */
@Configuration
public class CassandraConfig extends AbstractCassandraConfiguration {

    @Value("${spring.data.cassandra.keyspace-name}")
    private String keyspaceName;

    @Override
    protected String getKeyspaceName() {
        return keyspaceName;
    }

}

第6步:Department.java

package com.cassandra.sample.domain;

import org.springframework.data.cassandra.mapping.Column;
import org.springframework.data.cassandra.mapping.UserDefinedType;

@UserDefinedType("dept_details")
public class Department {
    @Column("dept_name")
    private String departmentName;
    @Column("dept_address")
    private String departmentAddress;
    public String getDepartmentName() {
        return departmentName;
    }
    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }
    public String getDepartmentAddress() {
        return departmentAddress;
    }
    public void setDepartmentAddress(String departmentAddress) {
        this.departmentAddress = departmentAddress;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((departmentAddress == null) ? 0 : departmentAddress.hashCode());
        result = prime * result + ((departmentName == null) ? 0 : departmentName.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;
        Department other = (Department) obj;
        if (departmentAddress == null) {
            if (other.departmentAddress != null)
                return false;
        } else if (!departmentAddress.equals(other.departmentAddress))
            return false;
        if (departmentName == null) {
            if (other.departmentName != null)
                return false;
        } else if (!departmentName.equals(other.departmentName))
            return false;
        return true;
    }

}

第7步:Employee.java

package com.cassandra.sample.domain;

import java.util.Set;

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

@Table("emp_details")
public class Employee {
    @PrimaryKey("emp_id")   
    private int employeeId;
    @Column("emp_name")
    private String employeeName;
    @Column("emp_designation")
    private String designation;
    @Column("dept_info")
    private Set<Department> departmentDetails;
    public int getEmployeeId() {
        return employeeId;
    }
    public void setEmployeeId(int employeeId) {
        this.employeeId = employeeId;
    }
    public String getEmployeeName() {
        return employeeName;
    }
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }
    public String getDesignation() {
        return designation;
    }
    public void setDesignation(String designation) {
        this.designation = designation;
    }
    public Set<Department> getDepartmentDetails() {
        return departmentDetails;
    }
    public void setDepartmentDetails(Set<Department> departmentDetails) {
        this.departmentDetails = departmentDetails;
    }       

}

第8步:EmployeeRepository.java

package com.cassandra.sample.repository;

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

import com.cassandra.sample.domain.Employee;

public interface EmployeeRepository extends CassandraRepository<Employee> {
    Employee findByEmployeeId(int employeeId);
    void deleteByEmployeeId(Integer employeeId, Class<Employee> employee) ;

}

第9步:EmployeeRepositoryTest.java

package com.cassandra.sample.repository;

import java.util.HashSet;
import java.util.Set;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.cassandra.sample.domain.Department;
import com.cassandra.sample.domain.Employee;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class EmployeeRepositoryTest {

    @Autowired
    private EmployeeRepository employeeRepository;

    // Note: Comment or UnComment the test methods as per the db-operation you are performing

    /*@Test
    public void insertEmployee(){

        Employee employee = prepareEmployee();      
        employeeRepository.save(employee);

    }*/

    @Test
    public void retrieveEmployee(){
        Iterable<Employee> employees=employeeRepository.findAll();
        for(Employee emp:employees){
            System.out.println("Employee name :"+emp.getEmployeeName());
            Set<Department> departments=emp.getDepartmentDetails();
            for(Department dept:departments){
                System.out.println("Department Name :"+dept.getDepartmentName());
            }
        }

    }

    /*@Test
    public void updateEmployee(){

        Employee employee=employeeRepository.findByEmployeeId(421);
        employee.setEmployeeName("Test Employee Updated");
        employee.setDesignation("SSE");

        Set<Department> departments=employee.getDepartmentDetails();
        Department department1=new Department();
        department1.setDepartmentName("Civil");
        department1.setDepartmentAddress("Test Dept Addr 3");
        departments.add(department1);
        employee.setDepartmentDetails(departments);
        employeeRepository.save(employee);
    }*/

    /*@Test
    public void deleteEmployee(){
        employeeRepository.delete(employeeRepository.findByEmployeeId(421));
    }*/

    private Employee prepareEmployee() {
        Set<Department> departments = prepareDepartments();
        Employee employee=new Employee();
        employee.setEmployeeId(421);
        employee.setEmployeeName("Test Employee");
        employee.setDesignation("Tech Lead");
        employee.setDepartmentDetails(departments);
        return employee;
    }

    private Set<Department> prepareDepartments() {
        Set<Department> departments=new HashSet<>();
        Department department1=new Department();
        department1.setDepartmentName("EEE");
        department1.setDepartmentAddress("Test Dept Addr 1");
        departments.add(department1);
        Department department2=new Department();
        department2.setDepartmentName("CSE");
        department2.setDepartmentAddress("Test Dept Addr 2");
        departments.add(department2);
        return departments;
    }


}