2014-10-26 55 views
9

我已經做了一個實驗......兩個彈簧數據的存儲庫一個共同的實體: - JPA - MongoDB的春天的數據mongodb。生成的ID的錯誤

首先我使用下列庫版本:

彈簧DATA- JPA:1.7.0.RELEASE 彈簧數據的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回購itory具有以下外觀:

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: 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) 

我認爲這是一個非常普遍的情況下,爲什麼沒有春天能夠產生實體ID爲Long數據?這太不可思議。

+0

當我加入註解** @ GeneratedValue **我的IDE在那裏和那裏拋出一個錯誤。我在我的'pom.xml'文件中使用了** jpa **依賴項,但即使這樣也不能正常工作,因爲它搜索的是MySQL數據庫,而我正在使用NoSQL(mongoDB)。所以,如果你可以幫助我的東西,請做。提前致謝。 – Learner 2017-03-31 09:08:26

+0

@Neil Stockton當我添加註釋** @ GeneratedValue **時,我的IDE在那裏和那裏拋出一個錯誤。我在我的'pom.xml'文件中使用了** jpa **依賴項,但即使這樣也不能正常工作,因爲它搜索的是MySQL數據庫,而我正在使用NoSQL(mongoDB)。所以,如果你可以幫助我的東西,請做。在此先感謝.. – Learner 2017-03-31 09:09:37

回答

17

蒙戈的ObjectID不映射到Java長型。

我看到這個在doc umentation,在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. 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.

所以更改ID爲String或BigInteger和刪除策略的說法。

+0

然後,我將失去兼容性與Spring JPA實現:( – b3lowster 2014-10-26 16:12:56

+0

@Robert Moskal當我添加註釋** @ GeneratedValue **我的IDE是拋出一個錯誤,然後在那裏我已經使用** jpa * *依賴於我的'pom.xml'文件,但即使這樣也不行,因爲我搜索的是MySQL數據庫,而且我使用的是NoSQL(mongoDB),所以如果你能幫助我做些什麼,請做。 – Learner 2017-03-31 09:11:08

+0

添加新問題並標記我 – 2017-03-31 11:35:54

1

使用@Id作爲字符串正常工作。

請確保您的存儲庫的String(相同類型@Id)擴展:

extends MongoRepository<MyEntity, String> 
1

我想這樣的事情太多,對於蒙戈DB我不得不使用import org.springframework.data.annotation.Id;版本的@Id而JPA我用import javax.persistence.Id;

1

我認爲問題在於您使用的是「實體」而不是「文檔」。 Mongo dao應該使用「Document」註釋,並且存儲庫應該擴展「MongoRepository」接口。這將是一個使用你所擁有的例子。首先你要蒙戈依賴添加到您的POM(我假設你正在使用的彈簧引導家長,所以版本號都會有定義)

<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 
} 
0

使用Spring數據休息+蒙戈我的項目

  1. 數據類型 我沒有使用Long或BigInteger中的任何一種。它是自定義的對象。讓我們說CompanyUID.class。這裏它必須是MongoRepository<DataLoadMerchant, CompanyUID> @Miguel所說的 然後我改變了我的getter和setter。字符串轉換爲CompanyUID或CompanyUID爲String

  2. 寄存器轉換器蒙戈

    @Configuration 
    public class MongoConfig extends AbstractMongoConfiguration { 
    @Override 
    public CustomConversions customConversions() { 
        converters.add(new CompanyUIDoObjectIdConverter()); 
        converters.add(new ObjectIdToCompanyUIDConverter()); 
        return new CustomConversions(converters); 
        } 
    } 
    
  3. 列名。 我看着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; 
     } 
    }