Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring data mongodb. Generating id's error

Tags:

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.

like image 313
b3lowster Avatar asked Oct 26 '14 15:10

b3lowster


2 Answers

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.

like image 162
Robert Moskal Avatar answered Oct 04 '22 21:10

Robert Moskal


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>
like image 44
Miguel Reyes Avatar answered Oct 04 '22 23:10

Miguel Reyes