2

「ユーザー」ドキュメントの複数のフィールドを同時に更新しようとしています。ただし、一部のフィールドのみを更新し、ドキュメント全体を置き換えたくないので、後者は避けられないようです。これを行うために私が持っている方法は次のようになります:

public void mergeUser(User user) {
    Update mergeUserUpdate = new Update();
    mergeUserUpdate.set("firstName", user.getFirstName());
    mergeUserUpdate.set("lastName", user.getLastName());
    mergeUserUpdate.set("username", user.getUsername());

    mongoTemplate.updateFirst(new Query(Criteria.where("_id").is(user.getId())), mergeUserUpdate, User.class);
}

私のユーザーオブジェクトには他のフィールド(passwordフィールドはその1つです)が含まれていますが、これが値に設定されている場合は、すぐに空の文字列に置き換えられるか、完全に削除されます。したがって、データベースでは、これは次のとおりです。

{
  "_id" : ObjectId("4fc34563c3276c69248271d8"),
  "_class" : "com.test.User",
  "password" : "d26b7f5c0ed888e46889dd1e3d217816d070510596f495e156e9efe4b035fec5a1fe1be643955359",
  "username" : "john@gmail.com",
  "alias" : "john"
}

mergeUserメソッドを呼び出した後、これに置き換えられます。

{
  "_id" : ObjectId("4fc34563c3276c69248271d8"),
  "_class" : "com.test.User",
  "username" : "john@gmail.com",
  "firstName" : "John",
  "lastName" : "Doe",
  "address" : {
    "addressLine1" : ""
  }
}

Updateオブジェクトを見ると、次のものが含まれていることがわかります。

{$set={firstName=John, lastName=Doe, username=john@gmail.com}}

これは私には正しいように見え、MongoDB$set関数の理解から、これは指定された値のみを設定する必要があります。したがって、パスワードフィールドは変更されず、他のフィールドはそれに応じて追加または変更されることを期待していました。

一般的な議論のポイントとして、私は最終的に、Springが提供されたUserオブジェクトに存在するフィールドを自動的にチェックし、入力された値でのみデータベースを更新する、ある種の「マージ」機能を実現しようとしています。すべてのフィールド。それは理論的には可能だと私は思っていたでしょう。誰かがこれを行うための良い方法を知っていますか?

念のため、これが私のユーザーオブジェクトです。

/**
 * Represents an application user.
 */
@Document(collection = "users")
public class User {

    @Id
    private String id;

    @NotEmpty( groups={ChangePasswordValidationGroup.class} )
    private String password;

    @Indexed
    @NotEmpty
    @Email
    private String username;

    private String firstName;

    private String lastName;

    private Date dob;

    private Gender gender;

    private Address address;

    public enum Gender {
        MALE, FEMALE
    }

    // /////// GETTERS AND SETTERS ///////////

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Date getDob() {
        return dob;
    }

    public void setDob(Date dob) {
        this.dob = dob;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Gender getGender() {
        return gender;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getAlias() {
        return alias;
    }

    public void setAlias(String alias) {
        this.alias = alias;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}
4

2 に答える 2

2

上記のコードは問題なく動作します。私はばかげた間違いを犯しました。正しく更新した後、ユーザー オブジェクトを再度保存し、新しいドキュメントに置き換えてしまいました。

于 2012-05-29T08:41:06.833 に答える
1

Spring MongoTemplate を使用して、いくつかのフィールドなしでエンティティを更新する別のソリューションがあります。

DBObject userDBObject = (DBObject) mongoTemplate.getConverter().convertToMongoType(user);
//remove unnecessary fields    
userDBObject.removeField("_id");
userDBObject.removeField("password");

//Create setUpdate & query
Update setUpdate = Update.fromDBObject(new BasicDBObject("$set", userDBObject));
mongoTemplate.updateFirst(new Query(Criteria.where("_id").is(user.getId())), setUpdate , User.class);

//Or use native mongo
//mongoTemplate.getDb().getCollection("user").update(new BasicDBObject("_id",user.getId())
        , new BasicDBObject("$set", userDBObject), false, false);

自動変換を使用するため、エンティティに多くのフィールドがある場合に非常に役立ちます。

于 2014-03-28T04:34:19.553 に答える