Java Spring 数据 mongodb。生成 id 的错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26574409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring data mongodb. Generating id's error
提问by b3lowster
I have made an experiment... one common entity for two Spring data's repositories: - JPA - MongoDB
我做了一个实验......两个 Spring 数据存储库的一个通用实体:- JPA- MongoDB
first of all I' using following libraries versions:
首先,我使用以下库版本:
spring-data-jpa : 1.7.0.RELEASE spring-data-mongodb : 1.6.0.RELEASE
弹簧数据-jpa:1.7.0.RELEASE 弹簧数据-mongodb:1.6.0.RELEASE
I have an Entity:
我有一个实体:
@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 Repository has following look:
JPA 存储库具有以下外观:
public interface Repository extends CrudRepository<Account, Long> {
public Account findByNumber(String number);
}
MongoDB repository has following look:
MongoDB 存储库具有以下外观:
package ua.home.springdata.investigation.repository.mongo;
包 ua.home.springdata.investigation.repository.mongo;
public interface Repository extends CrudRepository<Account, Long> {
}
So... JPA works :) Nothing special :) But MongoDB test is not passed :( I'm getting an error:
所以... 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)
I think it's a very common case. Why is not Spring data able to generate entity id as Long? It's so weird.
我认为这是一个非常普遍的案例。为什么 Spring 数据不能将实体 ID 生成为 Long?这太奇怪了。
采纳答案by KayV
By default the id in mongo collection is string. To maintain a long id of obejcts in collection, you can choose a separate field as follows:
默认情况下,mongo 集合中的 id 是字符串。要在集合中维护一个很长的 id 对象,您可以选择一个单独的字段,如下所示:
@Id
@Field("_id")
@JsonIgnore
private String id;
@Field("my_object_id")
private Long myObjectId;
回答by Robert Moskal
Mongo ObjectIds don't map to a java Long type.
Mongo ObjectIds 不映射到 java Long 类型。
I see this in the documentation, under 7.6.1:
我在 7.6.1 下的文档中看到了这一点:
http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo-template.id-handling
http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo-template.id-handling
An id property or field declared as a String in the Java class will be converted to and stored as an ObjectId if possible using a Spring Converter. Valid conversion rules are delegated to the MongoDB Java driver. If it cannot be converted to an ObjectId, then the value will be stored as a string in the database.
An id property or field declared as BigInteger in the Java class will be converted to and stored as an ObjectId using a Spring Converter.
如果可能,使用 Spring 转换器将在 Java 类中声明为 String 的 id 属性或字段转换为 ObjectId 并将其存储。有效的转换规则委托给 MongoDB Java 驱动程序。如果无法转换为 ObjectId,则该值将作为字符串存储在数据库中。
在 Java 类中声明为 BigInteger 的 id 属性或字段将使用 Spring 转换器转换并存储为 ObjectId。
So change id to a String or a BigInteger and remove the strategy argument.
因此,将 id 更改为 String 或 BigInteger 并删除 strategy 参数。
回答by Miguel Reyes
Using @Id
as a String works fine.
使用@Id
作为一个String工作正常。
Make sure that your Repository extends with a String (same type as the @Id):
确保您的 Repository 扩展了一个字符串(与@Id 的类型相同):
extends MongoRepository<MyEntity, String>
回答by Romell
I tried something like this too, for mongo db I had to use the import org.springframework.data.annotation.Id;
version of @Id
whereas JPA I used import javax.persistence.Id;
我也尝试过类似的方法,对于 mongo db,我必须使用我使用的 JPAimport org.springframework.data.annotation.Id;
版本@Id
import javax.persistence.Id;
回答by GSUgambit
I think the problem is that you are using Entity
instead of Document
. Mongo dao's should use Document
annotation and the repository should extend the MongoRepository
interface. This would be an example using what you have. First you'll want to add the mongo dependency to your pom (I assume you are using spring boot parent, so version number will be defined there)
我认为问题在于您正在使用Entity
而不是Document
. Mongo dao 应该使用Document
注解,并且存储库应该扩展MongoRepository
接口。这将是一个使用您所拥有的示例。首先,您需要将 mongo 依赖项添加到您的 pom(我假设您使用的是 spring boot parent,因此版本号将在那里定义)
<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
}
回答by cicidi
My project using Spring Data Rest + mongo
我的项目使用 Spring Data Rest + mongo
Data type I am not using either type of
Long
orBigInteger
. It is customized Object. Let's sayCompanyUID.class
. Here it has to beMongoRepository<DataLoadMerchant, CompanyUID>
as what @Miguel says Then I changed my getter and setter. ConvertString
toCompanyUID
orCompanyUID
toString
.register converter in Mongo
数据类型我没有使用任何类型的
Long
或BigInteger
。它是自定义对象。让我们说CompanyUID.class
。这里必须MongoRepository<DataLoadMerchant, CompanyUID>
像@Miguel所说的那样然后我改变了我的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);
}
}
- column name. I look at mongo document. it seems I can not have a entityId with @Id and also use entityId as my column name. So I change setter Then in MongoDB it will have 2 column One is _id and the other one is entityId. The two column keep the same value. And we only use entityId as the primary key for CRUD, even though it is not the true primary key
- 列名。我看mongo文件。似乎我不能使用带有 @Id 的 entityId 并且还使用 entityId 作为我的列名。所以我更改setter然后在MongoDB中它将有2列一个是_id,另一个是entityId。两列保持相同的值。我们只使用 entityId 作为 CRUD 的主键,即使它不是真正的主键
my code
我的代码
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;
}
}