2016-11-29 1 views
1

basé sur le tutoriel spring-data-cassandra-tutorial J'expérimente l'annotation UserDefinedType.UserDefinedType non trouvé par spring-data-cassandra

J'ai mis à jour le projet pour utiliser spring-data-cassandra: 1.5.0.BUILD-SNAPSHOT, ajouté le prix d'attribut au livre, implémenté le UserDefinedType correspondant et ajouté setInitialEntitySet et setUserTypeResolver à la configuration.

Quand je puis exécuter la BookRepositoryIntegrationTest contre un cassandra 3.9, je reçois l'erreur suivante:

org.springframework.data.mapping.model.MappingException: Type d'utilisateur [prix] pas trouvé

Une idée de ce qui me manque?

Voici mes changements ...

Book.java:

package org.baeldung.spring.data.cassandra.model; 

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

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

@Table 
public class Book { 

    @PrimaryKeyColumn(name = "id", ordinal = 0, type = PrimaryKeyType.CLUSTERED, ordering = Ordering.DESCENDING) 
    private UUID id; 

    @PrimaryKeyColumn(name = "title", ordinal = 1, type = PrimaryKeyType.PARTITIONED) 
    private String title; 

    @PrimaryKeyColumn(name = "publisher", ordinal = 2, type = PrimaryKeyType.PARTITIONED) 
    private String publisher; 

    @Column 
    private Set<String> tags = new HashSet<>(); 

    private Price price; 

    public Book(final UUID id, final String title, final String publisher, final Set<String> tags) { 
     this.id = id; 
     this.title = title; 
     this.publisher = publisher; 
     this.tags.addAll(tags); 
    } 
} 

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.baeldung</groupId> 
    <artifactId>spring-data-cassandra</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <name>spring-data-cassandra</name> 

    <properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 

     <org.springframework.version>4.3.4.RELEASE</org.springframework.version> 

     <org.springframework.data.version>1.5.0.BUILD-SNAPSHOT</org.springframework.data.version> 

     <junit.version>4.12</junit.version> 
     <org.slf4j.version>1.7.12</org.slf4j.version> 
     <logback.version>1.1.3</logback.version> 
     <cassandra-driver-core.version>3.1.2</cassandra-driver-core.version> 
     <cassandra-unit.version>3.0.0.1</cassandra-unit.version> 
     <maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>   
    </properties> 

    <dependencies> 
     <dependency> 
      <groupId>org.springframework.data</groupId> 
      <artifactId>spring-data-cassandra</artifactId> 
      <version>${org.springframework.data.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-core</artifactId> 
      <version>${org.springframework.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-test</artifactId> 
      <version>${org.springframework.version}</version> 
      <scope>test</scope> 
     </dependency> 
     <dependency> 
      <groupId>org.cassandraunit</groupId> 
      <artifactId>cassandra-unit-spring</artifactId> 
      <version>${cassandra-unit.version}</version> 
      <scope>test</scope> 
      <exclusions> 
       <exclusion> 
        <groupId>org.cassandraunit</groupId> 
        <artifactId>cassandra-unit</artifactId> 
       </exclusion> 
      </exclusions> 
     </dependency> 
     <dependency> 
      <groupId>org.cassandraunit</groupId> 
      <artifactId>cassandra-unit</artifactId> 
      <version>${cassandra-unit.version}</version> 
      <scope>test</scope> 
     </dependency> 
     <dependency> 
      <groupId>com.datastax.cassandra</groupId> 
      <artifactId>cassandra-driver-core</artifactId> 
      <version>${cassandra-driver-core.version}</version> 
      <optional>true</optional> 
     </dependency> 
     <dependency> 
      <groupId>org.slf4j</groupId> 
      <artifactId>slf4j-api</artifactId> 
      <version>${org.slf4j.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>ch.qos.logback</groupId> 
      <artifactId>logback-classic</artifactId> 
      <version>${logback.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.slf4j</groupId> 
      <artifactId>jcl-over-slf4j</artifactId> 
      <version>${org.slf4j.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.slf4j</groupId> 
      <artifactId>log4j-over-slf4j</artifactId> 
      <version>${org.slf4j.version}</version> 
     </dependency> 
    </dependencies> 
    <build> 
     <plugins> 
      <plugin> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>2.3.2</version> 
       <configuration> 
        <source>1.8</source> 
        <target>1.8</target> 
       </configuration> 
      </plugin> 
        <plugin> 
         <groupId>org.apache.maven.plugins</groupId> 
         <artifactId>maven-surefire-plugin</artifactId> 
         <version>${maven-surefire-plugin.version}</version> 
         <configuration> 
          <excludes> 
           <exclude>**/*IntegrationTest.java</exclude> 
           <exclude>**/*LiveTest.java</exclude> 
          </excludes> 
         </configuration> 
        </plugin> 
       </plugins> 
      </build> 

    <profiles> 
     <profile> 
      <id>integration</id> 
      <build> 
       <plugins> 
        <plugin> 
         <groupId>org.apache.maven.plugins</groupId> 
         <artifactId>maven-surefire-plugin</artifactId> 
         <executions> 
          <execution> 
           <phase>integration-test</phase> 
           <goals> 
            <goal>test</goal> 
           </goals> 
           <configuration> 
            <excludes> 
             <exclude>**/*LiveTest.java</exclude> 
            </excludes> 
            <includes> 
             <include>**/*IntegrationTest.java</include> 
            </includes> 
           </configuration> 
          </execution> 
         </executions> 
         <configuration> 
          <systemPropertyVariables> 
           <test.mime>json</test.mime> 
          </systemPropertyVariables> 
         </configuration> 
        </plugin> 
       </plugins> 
      </build> 
     </profile> 
    </profiles> 
</project> 

CassandraConfig.java

package org.baeldung.spring.data.cassandra.config; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.baeldung.spring.data.cassandra.model.Book; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.PropertySource; 
import org.springframework.core.env.Environment; 
import org.springframework.data.cassandra.config.CassandraClusterFactoryBean; 
import org.springframework.data.cassandra.config.CassandraEntityClassScanner; 
import org.springframework.data.cassandra.config.java.AbstractCassandraConfiguration; 
import org.springframework.data.cassandra.mapping.BasicCassandraMappingContext; 
import org.springframework.data.cassandra.mapping.CassandraMappingContext; 
import org.springframework.data.cassandra.mapping.SimpleUserTypeResolver; 
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories; 

@Configuration 
@PropertySource(value = { "classpath:cassandra.properties" }) 
@EnableCassandraRepositories(basePackages = "org.baeldung.spring.data.cassandra.repository") 
public class CassandraConfig extends AbstractCassandraConfiguration { 
    private static final Log LOGGER = LogFactory.getLog(CassandraConfig.class); 

    @Autowired 
    private Environment environment; 

    @Override 
    protected String getKeyspaceName() { 
     return environment.getProperty("cassandra.keyspace"); 
    } 

    @Override 
    @Bean 
    public CassandraClusterFactoryBean cluster() { 
     final CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean(); 
     cluster.setContactPoints(environment.getProperty("cassandra.contactpoints")); 
     cluster.setPort(Integer.parseInt(environment.getProperty("cassandra.port"))); 
     LOGGER.info("Cluster created with contact points [" + environment.getProperty("cassandra.contactpoints") + "] " + "& port [" + Integer.parseInt(environment.getProperty("cassandra.port")) + "]."); 
     return cluster; 
    } 

    @Override 
    @Bean 
    public CassandraMappingContext cassandraMapping() throws ClassNotFoundException { 
     BasicCassandraMappingContext ctx = new BasicCassandraMappingContext(); 
     ctx.setInitialEntitySet(CassandraEntityClassScanner.scan(Book.class)); 
     ctx.setUserTypeResolver(new SimpleUserTypeResolver(cluster().getObject(), getKeyspaceName())); 
     return ctx; 
    } 
} 

Price.java:

package org.baeldung.spring.data.cassandra.model; 

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

@UserDefinedType 
public class Price { 

    @Column 
    private Double amount; 

    @Column 
    private String currency; 

    public Price(Double amount, String currency) { 
     this.amount = amount; 
     this.currency = currency; 
    } 

    public Double getAmount() { 
     return amount; 
    } 

    public String getCurrency() { 
     return currency; 
    } 
} 

Répondre

1

Essayez d'utiliser la classe CassandraConfig ci-dessous.

@Configuration 
@PropertySource(value = { "classpath:cassandra.properties" }) 
@EnableCassandraRepositories(basePackages = "org.baeldung.spring.data.cassandra.repository") 
public class CassandraConfig extends AbstractCassandraConfiguration { 
private static final Log LOGGER = LogFactory.getLog(CassandraConfig.class); 

@Autowired 
private Environment environment; 

@Override 
protected String getKeyspaceName() { 
    return environment.getProperty("cassandra.keyspace"); 
} 

@Override 
@Bean 
public CassandraClusterFactoryBean cluster() { 
    final CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean(); 
    cluster.setContactPoints(environment.getProperty("cassandra.contactpoints")); 
    cluster.setPort(Integer.parseInt(environment.getProperty("cassandra.port"))); 
    LOGGER.info("Cluster created with contact points [" + environment.getProperty("cassandra.contactpoints") + "] " + "& port [" + Integer.parseInt(environment.getProperty("cassandra.port")) + "]."); 
    return cluster; 
} 


@Bean 
public CassandraMappingContext mappingContext() throws ClassNotFoundException { 
    BasicCassandraMappingContext mappingContext = new BasicCassandraMappingContext(); 
    mappingContext.setInitialEntitySet(CassandraEntityClassScanner.scan("org.baeldung.spring.data.cassandra.model")); 
    mappingContext.setUserTypeResolver(new SimpleUserTypeResolver(cluster().getObject(),getKeyspaceName())); 
    return mappingContext; 
} 

@Bean 
public CassandraConverter converter() throws ClassNotFoundException { 
    return new MappingCassandraConverter(mappingContext()); 
} 

@Bean 
public CassandraSessionFactoryBean session() throws ClassNotFoundException { 
    CassandraSessionFactoryBean session = new CassandraSessionFactoryBean(); 
    session.setCluster(cluster().getObject()); 
    session.setKeyspaceName(getKeyspaceName()); 
    session.setConverter(converter()); 
    session.setSchemaAction(SchemaAction.RECREATE); 
    return session; 
    } 
} 
+0

Hey, fonctionne comme un charme! Ai-je raison de dire que le MappingCassandraConverter est l'astuce? De plus, j'ai dû ajouter des constructeurs par défaut à mes beans pour pouvoir les charger. Merci beaucoup :) – user1388903

+1

Content de l'entendre. Veuillez accepter la réponse afin qu'elle soit utile pour les autres. – abaghel

+0

question similaire est ici (http://stackoverflow.com/questions/38862460/user-defined-type-with-spring-data-cassandra/42036202#42036202). étapes à suivre pour faire fonctionner UDT avec Spring data Cassandra – denzal

0

Votre code semble bon mais manque la création de type d'utilisateur. Vous avez également configuré SimpleUserTypeResolver pour rechercher les types d'utilisateurs.

Type d'utilisateur [prix] pas trouvé signifie que le type d'utilisateur n'a pas été trouvé dans Cassandra.

Vous avez deux options sur la manière de résoudre ce problème:

  1. Vous créez vous-même de type défini par l'utilisateur.
  2. Utilisez SchemaAction.RECREATE lors de l'amorçage de l'application.

tutorial de Baeldung utilise la création de table dans le test de sorte que la création manuelle de type d'utilisateur avant la création de la table soit la meilleure option.

CreateUserTypeSpecification userTypeSpecification = mappingContext. 
          getCreateUserTypeSpecificationFor(mappingContext.getExistingPersistentEntity(Price.class)) 
          .ifNotExists(ifNotExists); 

cqlTemplate.execute(CreateUserTypeCqlGenerator.toCql(userTypeSpecification));