I have made an experiment... one common entity for two Spring data's repositories: - JPA - MongoDB
first of all I' using following libraries versions:
spring-data-jpa : 1.7.0.RELEASE spring-data-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:
public interface Repository extends CrudRepository<Account, Long> {
public Account findByNumber(String number);
}
MongoDB repository has following look:
package 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:
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.
Mongo ObjectIds don't map to a java Long type.
I see this in the documentation, under 7.6.1:
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<String, ObjectId>. 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<BigInteger, ObjectId>.
Change id to a String or a BigInteger and remove the strategy argument.
Using @Id
as a String works fine.
Make sure that your Repository extends with a String (same type as the @Id):
extends MongoRepository<MyEntity, String>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With