春季数据MongoDB。生成id的错误
Posted
技术标签:
【中文标题】春季数据MongoDB。生成id的错误【英文标题】:Spring data mongodb. Generating id's error 【发布时间】:2014-12-21 20:31:34 【问题描述】:我做了一个实验......两个 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 存储库具有以下外观:
包ua.home.springdata.investigation.repository.mongo;
public interface Repository extends CrudRepository<Account, Long>
所以... JPA 有效 :) 没什么特别的 :) 但是 MongoDB 测试没有通过:( 我收到一个错误:
org.springframework.dao.InvalidDataAccessApiUsageException:无法为 ua.home.springdata.investigation.entity.Account 类型的实体自动生成 java.lang.Long 类型的 id! 在 org.springframework.data.mongodb.core.MongoTemplate.assertUpdateableIdIfNotSet(MongoTemplate.java:1149) 在 org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate.java:878) 在 org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:833) 在 org.springframework.data.mongodb.repository.support.SimpleMongoRepository.save(SimpleMongoRepository.java:73) 在 org.springframework.data.mongodb.repository.support.SimpleMongoRepository.save(SimpleMongoRepository.java:88) 在 org.springframework.data.mongodb.repository.support.SimpleMongoRepository.save(SimpleMongoRepository.java:45) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:442) 在 org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:427) 在 org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:381) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) 在 com.sun.proxy.$Proxy26.save(未知来源)我认为这是一个非常普遍的情况。为什么 Spring 数据不能像 Long 一样生成实体 ID?太奇怪了。
【问题讨论】:
当我添加注释 @GeneratedValue 时,我的 IDE 会在那里抛出错误。我在我的“pom.xml”文件中使用了 jpa 依赖项,但即使这样也不起作用,因为我得到的是它搜索 mysql DB 并且我使用的是 NoSQL (mongoDB)。所以如果你能帮我做点什么,请做。提前致谢。 @Neil Stockton 当我添加注释 @GeneratedValue 时,我的 IDE 会在那里抛出错误。我在我的“pom.xml”文件中使用了 jpa 依赖项,但即使这样也不起作用,因为我得到的是它搜索 MySQL DB 并且我使用的是 NoSQL (mongoDB)。所以如果你能帮我做点什么,请做。提前谢谢.. 【参考方案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 并存储为 转换器。有效的转换规则委托给 MongoDB Java 驱动程序。如果无法转换为 ObjectId, 然后该值将作为字符串存储在数据库中。
在 Java 类中声明为 BigInteger 的 id 属性或字段将 使用 Spring 转换为 ObjectId 并存储为 转换器
。
将 id 更改为 String 或 BigInteger 并删除 strategy 参数。
【讨论】:
那么我将失去与 Spring JPA 实现的兼容性:( @Robert Moskal 当我添加注释 @GeneratedValue 时,我的 IDE 会在那里抛出错误。我在我的“pom.xml”文件中使用了 jpa 依赖项,但即使这样也不起作用,因为我得到的是它搜索 MySQL DB 并且我使用的是 NoSQL (mongoDB)。所以如果你能帮我做点什么,请做。提前致谢。 添加一个新问题并标记我【参考方案2】:默认情况下,mongo 集合中的 id 是字符串。要在collection中维护一个long id的objects,可以选择一个单独的字段,如下:
@Id
@Field("_id")
@JsonIgnore
private String id;
@Field("my_object_id")
private Long myObjectId;
【讨论】:
【参考方案3】:我认为问题在于您使用的是Entity
而不是Document
。 Mongo dao 应该使用 Document
注释,并且存储库应该扩展 MongoRepository
接口。这将是一个使用您所拥有的示例。首先,您需要将 mongo 依赖项添加到您的 pom 中(我假设您使用的是 spring boot 父级,因此将在此处定义版本号)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "ACCOUNTS")
public class Account
@Id
private String id;
....rest of properties
import org.springframework.data.mongodb.repository.MongoRepository;
public interface AccountRepository extends MongoRepository<Account, String>
//any extra queries needed
【讨论】:
【参考方案4】:我的项目使用 Spring Data Rest + mongo
数据类型
我没有使用Long
或BigInteger
中的任何一种。它是自定义对象。假设CompanyUID.class
。正如@Miguel 所说,这里必须是MongoRepository<DataLoadMerchant, CompanyUID>
然后我改变了我的getter和setter。将String
转换为CompanyUID
或将CompanyUID
转换为String
。
Mongo 中的寄存器转换器
@Configuration
public class MongoConfig extends AbstractMongoConfiguration
@Override
public CustomConversions customConversions()
converters.add(new CompanyUIDoObjectIdConverter());
converters.add(new ObjectIdToCompanyUIDConverter());
return new CustomConversions(converters);
-
列名。
我看 mongo 文件。看来我不能有一个带有@Id 的 entityId,也不能使用 entityId 作为我的列名。所以我改变了二传手
然后在 MongoDB 中它将有 2 列
一个是_id,另一个是entityId。两列保持相同的值。而且我们只使用 entityId 作为 CRUD 的主键,即使它不是真正的主键
我的代码
public class ClassA implements Serializable
@Id
public CompanyUID id;
public CompanyUID entityId;
public String getId()
return this.id.toString();
public void setId(String id)
if (id != null && this.entityId != null)
if (!id.equals(this.entityId))
throw new Exception();
this.id = new CompanyUID(id);
this.entityId = this.id;
public String getEntityId()
return entityId.toString();
public void setEntityId(String entityId)
if (this.id != null && entityId != null)
if (!id.equals(entityId))
throw new Exception();
this.entityId = new CompanyUID(entityId);
this.id = this.entityId;
【讨论】:
【参考方案5】:我也尝试过类似的方法,对于 mongo db,我必须使用 @Id
的 import org.springframework.data.annotation.Id;
版本,而 JPA 我使用 import javax.persistence.Id;
【讨论】:
【参考方案6】:使用@Id
作为字符串可以正常工作。
确保您的存储库以字符串(与@Id 相同的类型)扩展:
extends MongoRepository<MyEntity, String>
【讨论】:
以上是关于春季数据MongoDB。生成id的错误的主要内容,如果未能解决你的问题,请参考以下文章
linux安装mongodb数据库./mongod -f mongodb.conf失败或者error
mongodb启动服务时候报错。错误1067,进程意外终止。