web-dev-qa-db-ja.com

春のデータmongodb。 IDのエラーの生成

私は実験を行いました... 2つのSpringデータのリポジトリの1つの共通エンティティ:-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リポジトリの外観は次のとおりです。

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:タイプua.home.springdata.investigation.entity.Account!
のエンティティに対して、タイプJava.lang.LongのIDを自動生成できません!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(Nati veMethodAccessorImpl.Java:57)
 at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport $ QueryExecutorMethodInterceptor.executeMethodOn( RepositoryFactorySupport.Java:442)
 org.springframework.data.repository.core.support.RepositoryFactorySupport $ QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.Java:427)
 org.springframework.data.repository。 core.support.RepositoryFactorySupport $ QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.Java:381)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179)
 org.springframework。 aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.Java:207)
 at com.Sun.proxy。$ Proxy26.save(Unknown Source)

それは非常に一般的なケースだと思います。 SpringデータがエンティティIDをロングとして生成できないのはなぜですか?それはとても奇妙です。

16
b3lowster

Mongo ObjectIdはJava Long型にマップされません。

これは7.6.1のドキュメントにあります。

http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo-template.id-handling

JavaクラスでStringとして宣言されたidプロパティまたはフィールドは、可能であればSpring Converterを使用してObjectIdに変換され、保存されます。有効な変換ルールは、MongoDB Javaドライバーに委任されます。 ObjectIdに変換できない場合、値はデータベースに文字列として格納されます。

JavaクラスでBigIntegerとして宣言されたidプロパティまたはフィールドは、Spring Converterを使用してObjectIdに変換および格納されます。

したがって、idをStringまたはBigIntegerに変更し、strategy引数を削除します。

31
Robert Moskal

文字列として@Idを使用すると正常に機能します。

リポジトリが文字列(@Idと同じタイプ)で拡張されていることを確認します。

extends MongoRepository<MyEntity, String>
5
Miguel Reyes

問題は、EntityではなくDocumentを使用していることだと思います。 Mongo daoはDocumentアノテーションを使用し、リポジトリはMongoRepositoryインターフェースを拡張する必要があります。これはあなたが持っているものを使った例です。最初に、mongo依存関係を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
}
3
GSUgambit

私もこのようなものを試しました、mongo dbの場合はimport org.springframework.data.annotation.Id;バージョン@Id JPAを使用したのに対し、import javax.persistence.Id;

2
Romell

Spring Data Rest + mongoを使用する私のプロジェクト

  1. データ型LongBigIntegerのどちらのタイプも使用していません。カスタマイズされたオブジェクトです。まあ言ってみれば CompanyUID.class。ここではMongoRepository<DataLoadMerchant, CompanyUID> @Miguelの言うとおり、その後、ゲッターとセッターを変更しました。 StringCompanyUIDに、またはCompanyUIDStringに変換します。

  2. mongoのレジスタコンバータ

@Configuration
public class MongoConfig extends AbstractMongoConfiguration {
    @Override
    public CustomConversions customConversions() {
        converters.add(new CompanyUIDoObjectIdConverter());
        converters.add(new ObjectIdToCompanyUIDConverter());
        return new CustomConversions(converters);
    }
}
  1. 列名。 mongo文書を見る。 @IdでentityIdを使用できず、entityIdを列名として使用できないようです。したがって、セッターを変更すると、MongoDBには2つの列があります。1つは_idで、もう1つはentityIdです。 2つの列は同じ値を保持します。そして、それは本当の主キーではありませんが、CRUDの主キーとしてのみentityIdを使用します

私のコード

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