关于实体中缺少主属性的异常



我是一个新手与春季启动和卡桑德拉,我试图连接两者建立一个API。这个项目是用Scala编写的,也是为了从中学习。

这是主要的应用:

object Application {
def main(args: Array[String]): Unit = {
SpringApplication.run(classOf[Application], args: _*)
}
}
@SpringBootApplication(exclude = Array(classOf[CassandraDataAutoConfiguration], classOf[CassandraAutoConfiguration]))
class Application

这是个控制器:

@CrossOrigin
@RestController
@RequestMapping(value = Array("/api/user"))
class UserController @Autowired()(userService: UserService) {
@GetMapping(value = Array("/{email}"))
def findByEmail(@PathVariable("email") email: String): ResponseEntity[User] = {
try {
val user = userService.findByEmail(email)
if(user.isEmpty) {
return new ResponseEntity[User](HttpStatus.NOT_FOUND)
}
new ResponseEntity[User](user.get, HttpStatus.OK)
}
catch {
case _ => new ResponseEntity[User](HttpStatus.INTERNAL_SERVER_ERROR)
}
}
}

这是一个服务:

@Service
class UserService @Autowired()(userRepository: UserRepository) {
def findByEmail(email: String): Option[User] = userRepository.findByEmail(email)
}

这是一个仓库:

@Repository
trait UserRepository extends RepositoryBase[User, String] {
def findByEmail(email: String): Option[User] = {
this.findByPrimaryKey(email)
}
}

这是一个实体:

import javax.validation.constraints.{NotBlank, Size}
import org.springframework.data.cassandra.core.mapping.{CassandraType, Column, PrimaryKey, Table}
@Table(value = "user")
class User (
@NotBlank
@Column(value = "id")
@CassandraType(`type` = CassandraType.Name.UUID)
var id: String,
@NotBlank
@Size(min = 10)
@PrimaryKey(value = "email")
@CassandraType(`type` = CassandraType.Name.TEXT)
var email: String,
@NotBlank
@Size(min = 8, max = 250)
@Column(value = "password")
@CassandraType(`type` = CassandraType.Name.TEXT)
var password: String,
@NotBlank
@Size(min = 3)
@Column(value = "name")
@CassandraType(`type` = CassandraType.Name.TEXT)
var name: String
) extends Serializable {}

这是Cassandra的配置:

@Configuration
@EnableCassandraRepositories
case class CassandraConfig (
@Value(value = "${spring.data.cassandra.keyspace-name}")
keySpace: String,
@Value(value = "${spring.data.cassandra.contact-points}")
contactPoints: String,
@Value(value = "${spring.data.cassandra.port}")
port: Int
) extends AbstractCassandraConfiguration
{
override def getKeyspaceName: String = this.keySpace
override def getContactPoints: String = this.contactPoints
override def getPort: Int = this.port
@Bean
@throws(classOf[ClassNotFoundException])
override def cassandraMapping(): CassandraMappingContext = {
new BasicCassandraMappingContext()
}
}

这是表cql:

CREATE TABLE IF NOT EXISTS user_data.user (
id uuid,
email text,
password text,
name text,
PRIMARY KEY (email)
) WITH comment = 'user data';

我一直在阅读所有的春季启动文档,并在我的实体我有@Table和@PrimaryKey注释,但我仍然得到这个错误:

at org.springframework.data.cassandra.core.mapping.BasicCassandraPersistentEntityMetadataVerifier.fail(BasicCassandraPersistentEntityMetadataVerifier.java:117) ~[spring-data-cassandra-3.4.1.jar:3.4.1]
at org.springframework.data.cassandra.core.mapping.BasicCassandraPersistentEntityMetadataVerifier.verify(BasicCassandraPersistentEntityMetadataVerifier.java:90) ~[spring-data-cassandra-3.4.1.jar:3.4.1]
at org.springframework.data.cassandra.core.mapping.CompositeCassandraPersistentEntityMetadataVerifier.lambda$verify$0(CompositeCassandraPersistentEntityMetadataVerifier.java:67) ~[spring-data-cassandra-3.4.1.jar:3.4.1]
at java.util.Arrays$ArrayList.forEach(Arrays.java:3880) ~[na:1.8.0_312]
at org.springframework.data.cassandra.core.mapping.CompositeCassandraPersistentEntityMetadataVerifier.verify(CompositeCassandraPersistentEntityMetadataVerifier.java:67) ~[spring-data-cassandra-3.4.1.jar:3.4.1]
at org.springframework.data.cassandra.core.mapping.BasicCassandraPersistentEntity.verify(BasicCassandraPersistentEntity.java:157) ~[spring-data-cassandra-3.4.1.jar:3.4.1]
at org.springframework.data.mapping.context.AbstractMappingContext.doAddPersistentEntity(AbstractMappingContext.java:452) ~[spring-data-commons-2.7.1.jar:2.7.1]
at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:406) ~[spring-data-commons-2.7.1.jar:2.7.1]
at org.springframework.data.cassandra.core.mapping.CassandraMappingContext.addPersistentEntity(CassandraMappingContext.java:337) ~[spring-data-cassandra-3.4.1.jar:3.4.1]
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:291) ~[spring-data-commons-2.7.1.jar:2.7.1]
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:209) ~[spring-data-commons-2.7.1.jar:2.7.1]
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:92) ~[spring-data-commons-2.7.1.jar:2.7.1]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$6(RepositoryFactoryBeanSupport.java:326) ~[spring-data-commons-2.7.1.jar:2.7.1]
at java.util.Optional.ifPresent(Optional.java:159) ~[na:1.8.0_312]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:326) ~[spring-data-commons-2.7.1.jar:2.7.1]
at org.springframework.data.cassandra.repository.support.CassandraRepositoryFactoryBean.afterPropertiesSet(CassandraRepositoryFactoryBean.java:75) ~[spring-data-cassandra-3.4.1.jar:3.4.1]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.21.jar:5.3.21]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.21.jar:5.3.21]
... 45 common frames omitted
Suppressed: org.springframework.data.mapping.MappingException: @Table types must have only one primary attribute, if any; Found 0
at org.springframework.data.cassandra.core.mapping.BasicCassandraPersistentEntityMetadataVerifier.verify(BasicCassandraPersistentEntityMetadataVerifier.java:87) ~[spring-data-cassandra-3.4.1.jar:3.4.1]

可能是错误来自Cassandra配置吗?我也欢迎任何与bug无关的最佳实践建议。谢谢!

问题出在实体。实体的属性不能在构造函数中声明,这在Scala中通常是这样做的,因此实体可以被正确映射,属性必须以这种方式声明:

import javax.validation.constraints.{NotBlank, Size}
import org.springframework.data.cassandra.core.mapping.{CassandraType, Column, PrimaryKey, Table}
import scala.beans.BeanProperty
@Table(value = "user")
class User extends Serializable {
@NotBlank
@BeanProperty
@Column(value = "id")
@CassandraType(`type` = CassandraType.Name.UUID)
var id: String = _
@NotBlank
@BeanProperty
@Size(min = 10)
@PrimaryKey(value = "email")
@CassandraType(`type` = CassandraType.Name.TEXT)
var email: String = _
@NotBlank
@BeanProperty
@Size(min = 8, max = 250)
@Column(value = "password")
@CassandraType(`type` = CassandraType.Name.TEXT)
var password: String = _
@NotBlank
@BeanProperty
@Size(min = 3)
@Column(value = "name")
@CassandraType(`type` = CassandraType.Name.TEXT)
var name: String = _
}

[edit]看起来BasicCassandraPersistentEntityMetadataVerifier.java类正在寻找至少存在一个@PartitionKey

无论如何,我已经要求一个开发人员直接回答你的问题,因为我没有现成的例子给你。干杯!