在升级到Spring2.4.0之后,spring数据cassandra抛出了没有找到合适的转换器的异常
这是我的udt
@Setter
@Getter
@ToString
@NoArgsConstructor
@UserDefinedType(value="ADDRESS")
@AllArgsConstructor
public class Address implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String address1;
private String address2;
private String state;
private String city;
private String country;
private String zip;
private String longitude;
private String latitude;
}
这是我的主桌
package com.sellingsimplified.msor.common.schema;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.validation.constraints.NotEmpty;
import org.springframework.data.annotation.Id;
import org.springframework.data.cassandra.core.mapping.CassandraType;
import org.springframework.data.cassandra.core.mapping.CassandraType.Name;
import org.springframework.data.cassandra.core.mapping.Column;
import org.springframework.data.cassandra.core.mapping.PrimaryKey;
import org.springframework.data.cassandra.core.mapping.Table;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
@Table(value = "#{@contactCassandra}")
@Document(indexName = "#{@contactIndex}")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Contact implements Serializable,MSOREntity {
/**
*
*/
private static final long serialVersionUID = 5141439096729821675L;
@PrimaryKey
@Id
private Long contactid;// 1
private Long companyid;// 1
@CassandraType(type =Name.UDT, userTypeName = "NAME")
@Field(type = FieldType.Auto, includeInParent = true)
private com.sellingsimplified.msor.common.schema.Name contactname;// 1
@javax.validation.constraints.Email
private String corpemail;// 1
@CassandraType(type = Name.UDT, userTypeName = "EMAIL")
@Field(type = FieldType.Auto, includeInParent = true)
private Email contactemail;// 1
@NotEmpty(message="Jobtitle cannot be empty")
private String jobtitle;
private String skill;// newly added field
@CassandraType(type =Name.UDT, userTypeName = "ADDRESS")
@Field(type = FieldType.Auto, includeInParent = true)
@Column("contactaddress")
private Address contactaddress;
@CassandraType(type = Name.UDT, userTypeName = "PHONE")
@Field(type = FieldType.Auto, includeInParent = true)
private Phone contactphone;
private String companyname;
/**
* linkedinurl, facebookurl, twitterurl, xing_url, viadeo_url, misc_url
*/
private Map<String, String> contactsocialurl;
private String twitterhandle;
private String jobfunction;
private String createdby;
private String modifiedby;
private Date createdon;
private Date modifiedon;
private String updatedby;
private Date updatedon;
private String status;
private String contactverificationstatus;
private String copyaddress;
private String contactverified;
private String emailverified;
private String phonenumberverified;
private String senioritylevel;
private String contactsource;
private String lastmodifiedsystem;
private String domain;
private String comment;
private String processstatus;
private String enrichmentstage;
private String thresholdstatus;
private String incomingemailtype;
private String pageaccessedby;
private String groupid;
private String emailpattern;
private String emailcheck;
private String websitedomain;
private String humanhelp;
private String notVerifiedreason;
private String notVerifiedcomment;
private String zone;
private String companycheck;
private String industry;
private String employeetotal;
@CassandraType(type =Name.UDT, userTypeName = "NAME")
@Field(type = FieldType.Object, includeInParent = true)
private com.sellingsimplified.msor.common.schema.Name contactnamenl;
private String jobtitlenl;
@CassandraType(type = Name.UDT, userTypeName = "ADDRESS")
@Field(type = FieldType.Auto, includeInParent = true)
private Address contactaddressnl;
private String contacthash;
private String sourceurl;
@CassandraType(type = Name.UDT, userTypeName = "COMPANY")
@Field(type = FieldType.Auto, includeInParent = true)
private Company contactcompany;
private Long tokenid = -1L;
// new fields
private Map<String, String> customfields;
private Map<String, String> flags;
private Set<String> usertags;
private Set<String> systemtags;
private String user;
private String chromeuser;
private String experience;
private String notes;
@CassandraType(type = Name.UDT, userTypeName = "JobHistory")
@Field(type = FieldType.Auto, includeInParent = true)
private List<JobHistory> jobhistory;
private List<EmailHistory> emailhistory;
private String contactidtxt;
private Date lastaccessedate;
private Date ecmverifiedon;
private Date verifiedon;
private String isactive;
private String isverified;
private String isarchived;
private String isdeleted;
private Set<Long> mergedcontactids;
private String emaildomain;
private String contactotherfield1;
private String contactotherfield2;
private String contactotherfield3;
private String contactotherfield4;
private String contactotherfield5;
private String contactotherfield6;
private String contactotherfield7;
private String contactotherfield8;
private String contactotherfield9;
private String contactotherfield10;
private String linkedinurl;
private String facebookurl;
private String twitterurl;
private String miscurl;
private String linkedinhandle;
private String facebookhandle;
private String xinghandle;
private String viadeolinkhandle;
private String srcemail;
// new fields
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((contacthash == null) ? 0 : contacthash.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;
Contact other = (Contact) obj;
if (contacthash == null) {
if (other.contacthash != null)
return false;
} else if (!contacthash.equals(other.contacthash))
return false;
return true;
}
@Override
public EntityType entityType() {
// TODO Auto-generated method stub
return EntityType.CONTACT;
}
@Override
public String hash() {
// TODO Auto-generated method stub
return contacthash;
}
}
address是用户定义的类型,用于表contact。
我正在扩展abstractcassandraconfiguration以创建cassandra配置
package com.sellingsimplified.msor.common.cassandra;
import java.time.Duration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.cassandra.CassandraProperties;
import org.springframework.boot.autoconfigure.cassandra.CqlSessionBuilderCustomizer;
import org.springframework.boot.autoconfigure.cassandra.DriverConfigLoaderBuilderCustomizer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.AbstractCassandraConfiguration;
import org.springframework.data.cassandra.config.CqlSessionFactoryBean;
import org.springframework.data.cassandra.config.SchemaAction;
import org.springframework.data.cassandra.config.SessionBuilderConfigurer;
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
import com.datastax.oss.driver.api.core.CqlSessionBuilder;
import com.datastax.oss.driver.api.core.config.DefaultDriverOption;
import com.datastax.oss.driver.api.core.config.DriverConfigLoader;
@Configuration
@ConditionalOnProperty(value = "cassandra.enable", havingValue = "true", matchIfMissing = false)
@EnableCassandraRepositories(basePackages = "com.sellingsimplified.msor.common.repository")
public class CassandraConfig extends AbstractCassandraConfiguration {
@Value("${cassandra.table.contact:CONTACT}")
private String contactCassandra;
@Value("${cassandra.table.company:COMPANY}")
private String companyCassandra;
@Value("${spring.data.cassandra.contact-points}")
private String contactPoints;
@Value("${spring.data.cassandra.port}")
private int port;
@Value("${spring.data.cassandra.keyspace}")
private String keySpace;
@Value("${spring.data.cassandra.username}")
private String username;
@Value("${spring.data.cassandra.password}")
private String password;
@Value("${spring.data.cassandra.schema-action}")
private String schemaAction;
@Value("${cassandra.table.contact.history:ContactHistory}")
private String contactHistoryCassandra;
@Value("${cassandra.table.company.history:CompanyHistory}")
private String companyHistoryCassandra;
@Override
protected String getKeyspaceName() {
return keySpace;
}
@Override
protected String getContactPoints() {
return contactPoints;
}
@Override
protected int getPort() {
return port;
}
@Override
public SchemaAction getSchemaAction() {
return SchemaAction.valueOf(schemaAction);
}
protected boolean getMetricsEnabled() {
return false;
}
@Bean(name = "companyCassandra")
public String companyCassandra() {
return companyCassandra;
}
@Bean(name = "contactHistoryCassandra")
public String contactHistoryCassandra() {
return contactHistoryCassandra;
}
@Bean(name = "companyHistoryCassandra")
public String companyHistoryCassandra() {
return companyHistoryCassandra;
}
@Bean(name = "contactCassandra")
public String contactCassandra() {
return contactCassandra;
}
@Bean
public CqlSessionBuilderCustomizer authCustomizer(CassandraProperties properties) {
return (builder) -> builder.withAuthCredentials(properties.getUsername(), properties.getPassword());
}
@Bean
@Override
public CqlSessionFactoryBean cassandraSession() {
CqlSessionFactoryBean cassandraSession = super.cassandraSession();// super session should be called only once
cassandraSession.setUsername(username);
cassandraSession.setPassword(password);
cassandraSession.setLocalDatacenter("DC1");
return cassandraSession;
}
@Override
public String[] getEntityBasePackages() {
return new String[] { "com.sellingsimplified" };
}
@Override
protected SessionBuilderConfigurer getSessionBuilderConfigurer() {
return new SessionBuilderConfigurer() {
@Override
public CqlSessionBuilder configure(CqlSessionBuilder cqlSessionBuilder) {
return cqlSessionBuilder.withConfigLoader(DriverConfigLoader.programmaticBuilder()
.withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofMillis(15000))
.withDuration(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, Duration.ofSeconds(100))
.withBoolean(DefaultDriverOption.METADATA_SCHEMA_ENABLED, false)
.withDuration(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, Duration.ofSeconds(100))
.withDuration(DefaultDriverOption.CONTROL_CONNECTION_AGREEMENT_TIMEOUT, Duration.ofSeconds(100))
.withDuration(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofSeconds(100))
.withDuration(DefaultDriverOption.CONNECTION_CONNECT_TIMEOUT, Duration.ofSeconds(100)).build());
}
};
}
@Bean
DriverConfigLoaderBuilderCustomizer cassandraDriverCustomizer() {
return (builder) -> builder
.withDuration(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, Duration.ofSeconds(100))
.withBoolean(DefaultDriverOption.METADATA_SCHEMA_ENABLED, false)
.withDuration(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, Duration.ofSeconds(100))
.withDuration(DefaultDriverOption.CONTROL_CONNECTION_AGREEMENT_TIMEOUT, Duration.ofSeconds(100))
.withDuration(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofSeconds(100))
.withDuration(DefaultDriverOption.CONNECTION_CONNECT_TIMEOUT, Duration.ofSeconds(100));
}
}
保存联系人对象时出现以下异常
Caused by: org.springframework.data.cassandra.CassandraUncategorizedException: No converter found capable of converting from type [com.sellingsimplified.msor.common.schema.Address] to type [com.datastax.oss.driver.api.core.data.UdtValue]; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [com.sellingsimplified.msor.common.schema.Address] to type [com.datastax.oss.driver.api.core.data.UdtValue]
at org.springframework.data.cassandra.core.cql.CassandraExceptionTranslator.translate(CassandraExceptionTranslator.java:160) ~[spring-data-cassandra-3.1.1.jar:3.1.1]
at org.springframework.data.cassandra.core.cql.CassandraExceptionTranslator.translateExceptionIfPossible(CassandraExceptionTranslator.java:72) ~[spring-data-cassandra-3.1.1.jar:3.1.1]
at org.springframework.data.cassandra.config.CqlSessionFactoryBean.translateExceptionIfPossible(CqlSessionFactoryBean.java:646) ~[spring-data-cassandra-3.1.1.jar:3.1.1]
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-5.3.1.jar:5.3.1]
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242) ~[spring-tx-5.3.1.jar:5.3.1]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152) ~[spring-tx-5.3.1.jar:5.3.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.1.jar:5.3.1]
at com.sun.proxy.$Proxy135.save(Unknown Source) ~[na:na]
at com.sellingsimplified.msor.marchingengine.consumer.MSORGatewayEndpoint.processLead(MSORGatewayEndpoint.java:70) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_152]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_152]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_152]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_152]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:171) ~[spring-messaging-5.3.1.jar:5.3.1]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:120) ~[spring-messaging-5.3.1.jar:5.3.1]
at org.springframework.kafka.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:48) ~[spring-kafka-2.6.3.jar:2.6.3]
at org.springframework.kafka.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:321) ~[spring-kafka-2.6.3.jar:2.6.3]
at org.springframework.kafka.listener.adapter.BatchMessagingMessageListenerAdapter.invoke(BatchMessagingMessageListenerAdapter.java:170) ~[spring-kafka-2.6.3.jar:2.6.3]
at org.springframework.kafka.listener.adapter.BatchMessagingMessageListenerAdapter.onMessage(BatchMessagingMessageListenerAdapter.java:162) ~[spring-kafka-2.6.3.jar:2.6.3]
at org.springframework.kafka.listener.adapter.BatchMessagingMessageListenerAdapter.onMessage(BatchMessagingMessageListenerAdapter.java:58) ~[spring-kafka-2.6.3.jar:2.6.3]
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeBatchOnMessage(KafkaMessageListenerContainer.java:1744) [spring-kafka-2.6.3.jar:2.6.3]
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeBatchOnMessageWithRecordsOrList(KafkaMessageListenerContainer.java:1735) [spring-kafka-2.6.3.jar:2.6.3]
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeBatchOnMessage(KafkaMessageListenerContainer.java:1693) [spring-kafka-2.6.3.jar:2.6.3]
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeBatchListener(KafkaMessageListenerContainer.java:1622) [spring-kafka-2.6.3.jar:2.6.3]
... 7 common frames omitted
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [com.sellingsimplified.msor.common.schema.Address] to type [com.datastax.oss.driver.api.core.data.UdtValue]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:322) ~[spring-core-5.3.1.jar:5.3.1]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195) ~[spring-core-5.3.1.jar:5.3.1]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175) ~[spring-core-5.3.1.jar:5.3.1]
at org.springframework.data.mapping.model.ConvertingPropertyAccessor.convertIfNecessary(ConvertingPropertyAccessor.java:120) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.mapping.model.ConvertingPropertyAccessor.getProperty(ConvertingPropertyAccessor.java:91) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.cassandra.core.convert.MappingCassandraConverter.getWriteValue(MappingCassandraConverter.java:744) ~[spring-data-cassandra-3.1.1.jar:3.1.1]
at org.springframework.data.cassandra.core.convert.MappingCassandraConverter.writeMapFromWrapper(MappingCassandraConverter.java:490) ~[spring-data-cassandra-3.1.1.jar:3.1.1]
at org.springframework.data.cassandra.core.convert.MappingCassandraConverter.write(MappingCassandraConverter.java:456) ~[spring-data-cassandra-3.1.1.jar:3.1.1]
at org.springframework.data.cassandra.core.StatementFactory.insert(StatementFactory.java:307) ~[spring-data-cassandra-3.1.1.jar:3.1.1]
at org.springframework.data.cassandra.core.CassandraTemplate.doInsert(CassandraTemplate.java:632) ~[spring-data-cassandra-3.1.1.jar:3.1.1]
at org.springframework.data.cassandra.core.CassandraTemplate.insert(CassandraTemplate.java:622) ~[spring-data-cassandra-3.1.1.jar:3.1.1]
at org.springframework.data.cassandra.repository.support.SimpleCassandraRepository.save(SimpleCassandraRepository.java:93) ~[spring-data-cassandra-3.1.1.jar:3.1.1]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_152]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_152]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_152]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_152]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:524) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:531) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:156) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:131) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.1.jar:5.3.1]
at com.sun.proxy.$Proxy135.save(Unknown Source) ~[na:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_152]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_152]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_152]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_152]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.1.jar:5.3.1]
... 26 common frames omitted
1条答案
按热度按时间jjhzyzn01#
您将需要实现一个用
@Entity
Map到udt的。有关详细信息,请查看java驱动程序文档的entities页面。干杯!