我做了一个实验......两个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 Repository具有以下外观:
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数据不能生成实体ID为Long?这太奇怪了。
答案 0 :(得分:26)
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并删除策略参数。
答案 1 :(得分:4)
使用extends MongoRepository<MyEntity, String>
作为字符串可以正常工作。
确保您的存储库使用String扩展(与@Id类型相同):
onOptionsItemSelected()
答案 2 :(得分:3)
默认情况下,mongo集合中的id是字符串。要在收藏夹中保留较长的对象ID,您可以选择一个单独的字段,如下所示:
@Id
@Field("_id")
@JsonIgnore
private String id;
@Field("my_object_id")
private Long myObjectId;
答案 3 :(得分:2)
我认为问题在于您使用的是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
}
答案 4 :(得分:1)
我也尝试过类似的东西,对于mongo db我必须使用import org.springframework.data.annotation.Id;
版@Id
而JPA我使用import javax.persistence.Id;
答案 5 :(得分:0)
我的项目使用Spring Data Rest + mongo
数据类型
我没有使用任何类型的Long
或BigInteger
。它是自定义对象。让我们说CompanyUID.class
。正如@Miguel所说,它必须是MongoRepository<DataLoadMerchant, CompanyUID>
然后我改变了我的吸气剂和二传手。将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);
}
}
我的代码
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;
}
}