使用CassandraReporitory的findOne()或findAll()方法时,出现以下异常:
Caused by: java.lang.IllegalStateException: property does not have a single column mapping at org.springframework.data.cassandra.mapping.BasicCassandraPersistentProperty.getColumnName(BasicCassandraPersistentProperty.java:134) at org.springframework.data.cassandra.convert.BasicCassandraRowValueProvider.getPropertyValue(BasicCassandraRowValueProvider.java:64) at org.springframework.data.cassandra.convert.BasicCassandraRowValueProvider.getPropertyValue(BasicCassandraRowValueProvider.java:35) at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:78) at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:71) at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:83) at org.springframework.data.cassandra.convert.MappingCassandraConverter.readEntityFromRow(MappingCassandraConverter.java:133) at org.springframework.data.cassandra.convert.MappingCassandraConverter.readRow(MappingCassandraConverter.java:115) at org.springframework.data.cassandra.convert.MappingCassandraConverter.read(MappingCassandraConverter.java:200) at org.springframework.data.cassandra.repository.query.AbstractCassandraQuery.getSingleEntity(AbstractCassandraQuery.java:176) at org.springframework.data.cassandra.repository.query.AbstractCassandraQuery.execute(AbstractCassandraQuery.java:133) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:454) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:432)
我的课程定义如下:
@PrimaryKeyClass public class ItemAndLocationKey implements Serializable { private static final long serialVersionUID = 1L; @PrimaryKeyColumn(name = "itemId", ordinal = 0, type = PrimaryKeyType.PARTITIONED) @CassandraType(type = Name.UUID) private UUID itemId; @PrimaryKeyColumn(name = "locationId", ordinal = 1, type = PrimaryKeyType.CLUSTERED) @CassandraType(type = Name.UUID) private UUID locationId; public ItemAndLocationKey(UUID itemId, UUID locationId) { this.itemId = itemId; this.locationId = locationId; } public UUID getItemId() { return itemId; } public void setItemId(UUID itemId) { this.itemId = itemId; } public UUID getLocationId() { return locationId; } public void setLocationId(UUID locationId) { this.locationId = locationId; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ItemAndLocationKey that = (ItemAndLocationKey) o; if (!itemId.equals(that.itemId)) return false; return locationId.equals(that.locationId); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + itemId.hashCode(); result = prime * result + locationId.hashCode(); return result; } }
@Table(value = ItemAndLocation.tableName) public class ItemAndLocation { @org.springframework.data.annotation.Transient public static final String tableName = "ItemAndLocation"; @PrimaryKey private ItemAndLocationKey itemAndLocationKey; public ItemAndLocation(ItemAndLocationKey itemAndLocationKey) { this.itemAndLocationKey = itemAndLocationKey; } public ItemAndLocationKey getItemAndLocationKey() { return itemAndLocationKey; } public void setItemAndLocationKey(ItemAndLocationKey itemAndLocationKey) { this.itemAndLocationKey = itemAndLocationKey; } }
public interface ItemAndLocationRepository extends TypedIdCassandraRepository{ }
本质上,这里发生的是,在调用findOne()或findAll()期间从Cassandra中读取一行之后,spring数据cassandra尝试使用ClassGeneratingEntityInstantiator实例化不知道如何填充复合主键对象的ItemAndLocation对象, ItemAndLocationKey。我不知道如何提供自定义对象实例化器。当前版本没有示例或文档。
任何帮助都感激不尽。
我有同样的问题,问题出在用@Table注释的类中。
在您的方案中,您必须在以下类中删除重载的构造函数:
@Table(value = ItemAndLocation.tableName) public class ItemAndLocation { @org.springframework.data.annotation.Transient public static final String tableName = "ItemAndLocation"; @PrimaryKey private ItemAndLocationKey itemAndLocationKey; // \\\\\\\\\\\\\\\\\\\\ REMOVE THIS CONSTRUCTOR ////////////////// // public ItemAndLocation(ItemAndLocationKey itemAndLocationKey) { // this.itemAndLocationKey = itemAndLocationKey; // } // ////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ public ItemAndLocationKey getItemAndLocationKey() { return itemAndLocationKey; } public void setItemAndLocationKey(ItemAndLocationKey itemAndLocationKey) { this.itemAndLocationKey = itemAndLocationKey; } }
我希望这有帮助 :)