DuplicateKeyException:错误代码11000和错误消息' E11000'

时间:2017-08-24 21:23:20

标签: java mongodb spring-data-mongodb mongotemplate

我想仅使用id字段更新/替换文档,我正在使用mongoTemplate.save(p,collection)方法,但我收到DuplicateKeyException:错误代码11000和错误消息' E11000'



public class MongoDAO {
	
	@Autowired
	@Qualifier("mongoTemplate")
	private MongoTemplate mongoTemplate;
	
	private static final String PERSON_COLLECTION = "person";

	public MongoTemplate getMongoTemplate() {
		return mongoTemplate;
	}
	
  public void update(Object p) {
		this.mongoTemplate.save(p, PERSON_COLLECTION);
	}
  
 } 




这是我的人DAO



    public class PersonDAO{
      @Autowired
    	MongoDAO mongoDAO;

      public void updatePerson(){
      
         //read
    		Person p1 = mongoDAO.readById("1234");
    		
    		//update
    		p1.setName("David");
        mongoDAO.update(p1);
    		
     }
}




Person.java类



package com.mongo.andy;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Field;

public class Person {
	
	@Id
	private String id;
	@Field
	private String name;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	

}




我只想从mongodb获取对象更改值并根据_id更新文档 使用mongooperation.save()或mongotemplate.save()我得到以下错误



com.mongodb.DuplicateKeyException: Write failed with error code 11000 and error message 'E11000 duplicate key error collection: Person.person index: _id_ dup key: { : "5996f1d43b6af5c797a1cf4g" }'
	at com.mongodb.operation.BaseWriteOperation.convertBulkWriteException(BaseWriteOperation.java:236)
	at com.mongodb.operation.BaseWriteOperation.access$300(BaseWriteOperation.java:60)
	at com.mongodb.operation.BaseWriteOperation$1.call(BaseWriteOperation.java:146)
	at com.mongodb.operation.BaseWriteOperation$1.call(BaseWriteOperation.java:133)
	at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:230)
	at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:221)
	at com.mongodb.operation.BaseWriteOperation.execute(BaseWriteOperation.java:133)
	at com.mongodb.operation.BaseWriteOperation.execute(BaseWriteOperation.java:60)
	at com.mongodb.Mongo.execute(Mongo.java:781)
	at com.mongodb.Mongo$2.execute(Mongo.java:764)
	at com.mongodb.DBCollection.executeWriteOperation(DBCollection.java:333)
	at com.mongodb.DBCollection.insert(DBCollection.java:328)
	at com.mongodb.DBCollection.insert(DBCollection.java:319)
	at com.mongodb.DBCollection.insert(DBCollection.java:289)
	at com.mongodb.DBCollection.insert(DBCollection.java:255)
	at com.mongodb.DBCollection.insert(DBCollection.java:192)
	at org.springframework.data.mongodb.core.MongoTemplate$9.doInCollection(MongoTemplate.java:1051)
	at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:479)
	at org.springframework.data.mongodb.core.MongoTemplate.insertDBObject(MongoTemplate.java:1046)
	at org.springframework.data.mongodb.core.MongoTemplate.doInsert(MongoTemplate.java:855)
	at org.springframework.data.mongodb.core.MongoTemplate.doSaveVersioned(MongoTemplate.java:1001)
	at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:985)
	at com.mcmcg.dia.account.metadata.dao.MongoDAO.update(MongoDAO.java:105)
	at com.mcmcg.dia.account.metadata.service.AccountOALDService.mongotestapi(AccountOALDService.java:265)
	at com.mcmcg.dia.account.metadata.service.AccountOALDService$$FastClassBySpringCGLIB$$7f85f843.invoke(<generated>)
&#13;
&#13;
&#13;

请提供解决方案并建议是否有任何其他方法仅使用基于id字段的spring-data更新/替换mongodb中的文档。我有大型自定义对象,没有兴趣写任何更新的查询。 我可以使用upsert()在couchbase数据库中这样做,在mongodb中找到类似的方法。

1 个答案:

答案 0 :(得分:0)

而不是#Build the GUI; the next line has to NOT be indented [xml]$xaml = @" <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="Window" Title="Export Readable Prefs" WindowStartupLocation="CenterScreen" Width="600" Height="200" ShowInTaskbar="True"> <DockPanel Margin="5"> <ComboBox Grid.Row="0" x:Name="ComboNewTemplate" IsEditable="true" /> </DockPanel> </Window> "@ $reader = (New-Object System.Xml.XmlNodeReader $xaml) $Window = [Windows.Markup.XamlReader]::Load($reader) $comboNewTemplate = $Window.FindName("ComboNewTemplate") # this works $comboNewTemplate.Add_SelectionChanged({Write-Host $_.AddedItems[0]}) # this doesn't $comboNewTemplate.Add_TextBoxBase_TextChanged({Write-Host "text changed"}) # this doesn't, presumably because it hasn't been created yet $textBox = $comboNewTemplate.Template.FindName("PART_EditableTextBox", $comboNewTemplate) $textBox.Add_TextChanged({Write-Host "Text changed"}) # this doesn't; not even sure if this makes sense, it's out of my depth function qwe(){"text changed"} $func = qwe; [System.Runtime.InteropServices.Marshal]::StructureToPtr($func, $intptr, $true) $comboNewTemplate.AddHandler([System.Windows.Controls.Primitives.TextBoxBase]::TextChangedEvent, ` [System.Windows.RoutedEventHandler]::new($o1, $intptr)) $Window.ShowDialog() 尝试使用:

this.mongoTemplate.save(p, PERSON_COLLECTION);

该解决方案与public void update(Object p) { BasicDBObject dbObject = new BasicDBObject(); mongoTemplate.getConverter().write(p, dbObject); mongoTemplate.upsert(new Query(Criteria.where("_id").is(((Person) p).getId())), Update.fromDBObject(dbObject, "_id"), PERSON_COLLECTION); } 中实施upsert方法的方式类似。