2017-04-09 4 views
3

je tente de tester un insert d'un UDT Cassandra, et je continuer à courir dans l'erreur suivante: Exception dans le thread « principal » java.lang.IllegalArgumentException: UserTypeResolver ne doit pas être nulleUserTypeResolver ne doit pas être nul

Après juste essayer de comprendre ma propre chemin à travers, je tenté de reproduire exactement l'approche décrite dans ce qui suit: User Defined Type with spring-data-cassandra

Cependant, je reçois toujours la même erreur.

Je peux insérer dans la base de données cible lorsque je supprime l'UDT et insérez simplement les types simples, donc je sais que je me connecte de manière appropriée. Ma config est la suivante:

@Configuration 
@PropertySource(value = { "classpath:cassandra.properties" }) 
//@EnableCassandraRepositories(basePackages = { "org.spring.cassandra.example.repo" }) 
public class CassandraConfig { 

private static final Logger LOG = LoggerFactory.getLogger(CassandraConfig.class); 

@Autowired 
private Environment env; 

@Bean 
public CassandraClusterFactoryBean cluster() { 

    CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean(); 
    cluster.setContactPoints(env.getProperty("cassandra.contactpoints")); 
    cluster.setPort(Integer.parseInt(env.getProperty("cassandra.port"))); 

    return cluster; 
} 

@Bean 
public CassandraMappingContext mappingContext() { 
    BasicCassandraMappingContext mappingContext = new BasicCassandraMappingContext(); 
    mappingContext.setUserTypeResolver(new SimpleUserTypeResolver(cluster().getObject(), "campaign_management")); 
    return mappingContext; 
} 

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

@Bean 
public CassandraSessionFactoryBean session() throws Exception { 

    CassandraSessionFactoryBean session = new CassandraSessionFactoryBean(); 
    session.setCluster(cluster().getObject()); 
    session.setKeyspaceName(env.getProperty("cassandra.keyspace")); 
    session.setConverter(converter()); 
    session.setSchemaAction(SchemaAction.NONE); 

    return session; 
} 

@Bean 
public CassandraOperations cassandraTemplate() throws Exception { 
    return new CassandraTemplate(session().getObject()); 
} 
} 

Mon adresse et les classes employés sont exactement comme indiqué dans la question SO i référence ci-dessus, et mon principal est tout simplement:

public class MainClass { 

public static void main(String[] args) { 

ApplicationContext service = new AnnotationConfigApplicationContext(CassandraConfig.class); 

Employee employee = new Employee(); 
employee.setEmployee_id(UUID.randomUUID()); 
employee.setEmployee_name("Todd"); 
Address address = new Address(); 
address.setAddress_type("Home"); 
address.setId("ToddId"); 
employee.setAddress(address); 
CassandraOperations operations = service.getBean("cassandraTemplate", CassandraOperations.class); 

operations.insert(employee); 

System.out.println("Done"); 
} 
} 

J'utilise:

datastax.cassandra.driver.version=3.1.3 
spring.data.cassandra.version=1.5.1 
spring.data.commons.version=1.13.1 
spring.cql.version=1.5.1 

La version référencée dans la question SO précédente est 1.5.0, bien que spring.io liste 1.5.1 comme courant, donc j'utilise cela, et 1.5.0 n'est pas disponible.

Toute aide serait appréciée, car cela me rend un peu fou.

+0

Vous devez construire 'CassandraTemplate' avec' Session' et 'CassandraConverter'. – mp911de

+0

Merci, je suis nouveau au printemps, donc votre commentaire m'a aidé à me pousser dans la bonne direction. Je l'ai compris. – TBlank

+0

@TBlank Pouvez-vous publier votre solution? – TechEnthusiast

Répondre

0

En général, vous obtenez cette erreur lorsque vous manquez un UserTypeResolver sous votre cartographie cassandra, lui-même utilisé par le convertisseur cassandra, lui-même utilisé par le modèle Cassandra données Spring

Pour les détails:

Supposons que vous avoir un Spring MVC Controller de base opérationnel ailleurs ...

UserDefinedTypes dans Cassandra étant plus intéressant dans SETs et MAP, l'exemple ci-dessous est d'un tel type.

Exemple de configuration Spring Bean avec tous les paramètres par défaut (extrait de contexte d'application Spring XML):

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:cassandra="http://www.springframework.org/schema/data/cassandra" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:task="http://www.springframework.org/schema/task" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 
    http://www.springframework.org/schema/data/cassandra http://www.springframework.org/schema/data/cassandra/spring-cassandra.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> 
... 
<!-- ===== CASSANDRA ===== --> 
<!-- Loads the properties into the Spring Context and uses them to fill in placeholders in bean definitions below --> 
<context:property-placeholder location="/WEB-INF/spring/cassandra.properties" /> 

<!-- REQUIRED: The Cassandra Cluster --> 
<cassandra:cluster contact-points="${cassandra.contactpoints}" 
    port="${cassandra.port}" username="cassandra" password="cassandra" 
    auth-info-provider-ref="authProvider" /> 

<!-- REQUIRED: The Cassandra Session, built from the Cluster, and attaching to a keyspace --> 
<cassandra:session keyspace-name="${cassandra.keyspace}" /> 

<!-- REQUIRED: The Default Cassandra Mapping Context used by CassandraConverter 
    DO include a userTypeResolver for UDT support --> 
<cassandra:mapping entity-base-packages="fr.woobe.model"> 
    <cassandra:user-type-resolver keyspace-name="${cassandra.keyspace}" /> 
</cassandra:mapping> 

<!-- REQUIRED: The Default Cassandra Converter used by CassandraTemplate --> 
<cassandra:converter /> 

<bean id="authProvider" class="com.datastax.driver.core.PlainTextAuthProvider"> 
    <constructor-arg index="0" value="myCassandraUser" /> 
    <constructor-arg index="1" value="somePassword" /> 
</bean> 

<!-- REQUIRED: The Cassandra Template is the building block of all Spring Data Cassandra --> 
<cassandra:template id="cassandraTemplate" /> 
... 

puis en java, généralement dans votre contrôleur Spring MVC:

import org.springframework.data.cassandra.core.CassandraOperations; 
... 
// acquire DB template 
CassandraOperations cOps = this.beanFactory.getBean("cassandraTemplate", CassandraOperations.class); 
// for instance: load everything 
List<MyData> rows = cOps.select("SELECT * FROM mydatatable", MyData.class); 
// assuming an entry with index i exists... 
Set<Pair> mySetOfPairs = rows.get(i).pairSet; 
if (mySetOfPairs!=null) 
    for (Pair p : mySetOfPairs) { 
     ... handle p.first and p.second ... 
... 

avec ce genre d'entité mappings:

package example.model; 
import java.util.Set; 
import org.springframework.data.cassandra.core.mapping.CassandraType; 
import org.springframework.data.cassandra.core.mapping.PrimaryKey; 
import org.springframework.data.cassandra.core.mapping.Table; 
import com.datastax.driver.core.DataType.Name; 

@Table public class MyData { 
    @PrimaryKey 
    public String myKey; 
    // some other basic fields... 
    public String moreStuff; 
    // a SET of user defined 'pair type' 
    @CassandraType(type = Name.SET, userTypeName = "pairType") 
    public Set<Pair> pairSet; 

    // your constructors and other methods here... 
} 

et une entité définie par l'utilisateur comme:

package example.model; 
import org.springframework.data.cassandra.core.mapping.UserDefinedType; 

@UserDefinedType("pairType ") 
public class Pair { 
    public String first; 
    public String second; 

    public Pair() { 
    } 
    public Pair(String f, String s) { 
    this.first= f; 
    this.second= s; 
    } 
} 

tous basés sur une table Cassandra créée comme:

CREATE TYPE pairType (first text, second text); 

CREATE TABLE MyData (
    myKey text, 
    moreStuff text, 
    pairSet set<frozen<pairType>>, 
    PRIMARY KEY (myKey) 
) ; 

INSERT INTO MyData (myKey, moreStuff, pairSet) 
    VALUES ('hello', 'world', { 
        { first:'one', second:'two' }, 
        { first:'out', second:'there' } } 
     ) ; 

En terme d'artefacts Maven ou bibliothèques, printemps-webmvc est en effet nécessaire si vous exécutez dans un Web MVC Spring Controller, puis ressort -context-support, et spring-data-cassandra. Le pilote DataStax Cassandra vient en tant que dépendance.