春季数据 mongodb.生成 ID 的错误

我做了一个实验...两个Spring数据存储库的一个通用实体: - JPA - MongoDB

首先,我使用以下库版本:

spring-data-jpa : 1.7.0.RELEASE spring-data-mongodb : 1.6.0.RELEASE

我有一个实体:

@Entity
@Table(name = "ACCOUNTS")
public class Account {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ACCOUNT_ID")
    private Long id;

    @Column(name = "ACCOUNT_NUMBER")
    private String number;

    public Account() {
    }

    public Account(String number) {
        this.number = number;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }
}

JPA 存储库具有以下外观:

public interface Repository extends CrudRepository<Account, Long> {
    public Account findByNumber(String number);
}

MongoDB存储库具有以下外观:

package ua.home.springdata.investigation.repository.mongo;

public interface Repository extends CrudRepository<Account, Long> {
}

所以。。。JPA:)工作没什么特别:)但是MongoDB测试没有通过:(我收到一个错误:

org.springframework.dao.InvalidDataAccessApiUsageException: Cannot autogenerate id of type java.lang.Long for entity of type ua.home.springdata.investigation.entity.Account!
    at org.springframework.data.mongodb.core.MongoTemplate.assertUpdateableIdIfNotSet(MongoTemplate.java:1149)
    at org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate.java:878)
    at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:833)
    at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.save(SimpleMongoRepository.java:73)
    at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.save(SimpleMongoRepository.java:88)
    at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.save(SimpleMongoRepository.java:45)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:442)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:427)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:381)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy26.save(Unknown Source)

我认为这是一个非常普遍的情况。为什么 Spring 数据无法生成 Long 的实体 ID?这太奇怪了。


答案 1

Mongo ObjectIds不会映射到java Long类型。

我在7.6.1下的文档中看到了这一点:

http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo-template.id-handling

如果可能,Java 类中声明为 String 的 id 属性或字段将使用 Spring 转换器<字符串、ObjectId>转换为 ObjectId 并将其存储。有效的转换规则被委托给MongoDB Java驱动程序。如果无法将其转换为 ObjectId,则该值将作为字符串存储在数据库中。

在 Java 类中声明为 BigInteger 的 id 属性或字段将使用 Spring Converter<BigInteger、ObjectId> 转换为 ObjectId 并将其存储为 ObjectId。

将 id 更改为字符串或 BigInteger,并删除策略参数。


答案 2

用作字符串工作正常。@Id

确保您的存储库使用字符串(与@Id相同类型)进行扩展:

extends MongoRepository<MyEntity, String>