草庐IT

mongodb - MongoTemplate.save 上出现意外的 OptimisticLockingException

coder 2023-10-29 原文

我正在尝试使用 MongoTemplate 存储一个名为 Person 的实体。由于我想使用乐观锁定,因此使用@Version 注释对实体进行版本控制。

当我尝试使用 MongoTemplate.save 将一个新的 Person 实体存储到一个空集合中时,我得到了 OptimisticLockingException。我没想到会这样,因为我正在创建一个新对象而不是更新现有对象。 (并且没有其他线程正在访问该集合。)

这是预期的行为,还是我做错了什么?

(如果我改用 MongoOperations.insert,一切正常。(不过我想使用保存,因为 CrudRepository 只有保存,没有更新。)如果我删除 @Version 注释,它也能正常工作。)

谢谢, 丹尼尔

我的实体类:

import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.mongodb.core.mapping.Document;

@Document
public class Person {

    @Version
    private long versionId;

    @Id
    private ObjectId id;

    private final String name;

    public Person(String name) {
        this.name = name;
    }

    public long getVersionId() {
        return versionId;
    }

    public ObjectId getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Person person = (Person) o;

        if (id != null ? !id.equals(person.id) : person.id != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return id != null ? id.hashCode() : 0;
    }
}

我的测试设置(使用 EmbedMongo 设置 MongoDb 实例):

import com.mongodb.Mongo;
import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodProcess;
import de.flapdoodle.embed.mongo.MongodStarter;
import de.flapdoodle.embed.mongo.config.MongodConfig;
import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.process.runtime.Network;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

public class MongoDbTest {

    private MongodExecutable mongodExe;
    private MongodProcess mongod;
    private Mongo mongo;
    private MongoOperations mongoOperations;

    @Before
    public void setUp() throws Exception {
        MongodStarter runtime = MongodStarter.getDefaultInstance();

        mongodExe = runtime.prepare(new MongodConfig(Version.Main.V2_0, 12345, Network.localhostIsIPv6()));
        mongod = mongodExe.start();
        mongo = new Mongo("localhost", 12345);

        MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongo, "database");

        MappingContext mappingContext = new MongoMappingContext();
        MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(mongoDbFactory, mappingContext);

        mongoOperations = new MongoTemplate(mongoDbFactory, mappingMongoConverter);
    }

    @After
    public void tearDown() {
       mongod.stop();
       mongodExe.stop();
    }

    @Test
    public void testSave() {
        Person person = new Person("Joe");
        mongoOperations.save(person);  // This call throws OptimisticLockingException.
    }
}

最佳答案

当版本属性的类型为 long 时,默认情况下它的值为 0,这似乎不被 Spring Data MongoDB 接受。

将 Person 类中的 versionId 类型更改为 Long/Integer。

@Version
private Long versionId;

关于mongodb - MongoTemplate.save 上出现意外的 OptimisticLockingException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15277730/

有关mongodb - MongoTemplate.save 上出现意外的 OptimisticLockingException的更多相关文章

  1. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  2. ruby-on-rails - rails : save file from URL and save it to Amazon S3 - 2

    从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex

  3. ruby - 使用 rbenv 和 ruby​​-build 构建 ruby​​ 失败,出现 undefined symbol : SSLv2_method - 2

    我正在尝试在配备ARMv7处理器的SynologyDS215j上安装ruby​​2.2.4或2.3.0。我用了optware-ng安装gcc、make、openssl、openssl-dev和zlib。我根据README中的说明安装了rbenv(版本1.0.0-19-g29b4da7)和ruby​​-build插件。.这些是随optware-ng安装的软件包及其版本binutils-2.25.1-1gcc-5.3.0-6gconv-modules-2.21-3glibc-opt-2.21-4libc-dev-2.21-1libgmp-6.0.0a-1libmpc-1.0.2-1libm

  4. ruby-on-rails - rails : check if the model was really saved in after_save - 2

    ActiveRecord用于在每次调用保存方法时调用after_save回调,即使模型没有更改并且没有生成插入/更新查询也是如此。这实际上是默认行为。在大多数情况下这没问题。但是一些after_save回调对模型是否实际保存的事情很敏感。有没有办法确定模型是否实际保存在after_save中?我正在运行以下测试代码:classStage 最佳答案 ActiveRecordusetocallafter_savecallbackeachtimesavemethodiscalledevenifthemodelwasnotchangedan

  5. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

    假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

  6. ruby-on-rails - rspec 测试 has_many :through and after_save - 2

    我有一个(我认为)相对简单的has_many:through与连接表的关系:classUser:user_following_thing_relationshipsendclassThing:user_following_thing_relationships,:source=>:userendclassUserFollowingThingRelationship还有这些rspec测试(我知道这些不一定是好的测试,这些只是为了说明正在发生的事情):describeThingdobefore(:each)do@user=User.create!(:name=>"Fred")@thing=

  7. ruby - 为什么 return 关键字会导致我的 'if block' 出现问题? - 2

    下面的代码工作正常:person={:a=>:A,:b=>:B,:c=>:C}berson={:a=>:A1,:b=>:B1,:c=>:C1}kerson=person.merge(berson)do|key,oldv,newv|ifkey==:aoldvelsifkey==:bnewvelsekeyendendputskerson.inspect但是如果我在“ifblock”中添加return,我会得到一个错误:person={:a=>:A,:b=>:B,:c=>:C}berson={:a=>:A1,:b=>:B1,:c=>:C1}kerson=person.merge(berson

  8. Ruby SSL 错误 - sslv3 警报意外消息 - 2

    我正在尝试在ruby​​脚本中连接到服务器https://www.xpiron.com/schedule。但是,当我尝试连接时:require'open-uri'doc=open('https://www.xpiron.com/schedule')我收到以下错误消息:OpenSSL::SSL::SSLError:SSL_connectreturned=1errno=0state=SSLv2/v3readserverhelloA:sslv3alertunexpectedmessagefrom/usr/local/lib/ruby/1.9.1/net/http.rb:678:in`conn

  9. ruby - 安装 tiny_tds 在 mac os 10.10.5 上出现错误 - 2

    我正在使用macos,我想使用ruby​​驱动程序连接到sqlserver。我想使用tiny_tds,但它给出了缺少free_tds的错误,但它已经安装了。怎么能过这个?~brewinstallfreetdsWarning:freetds-0.91.112alreadyinstalled~sudogeminstalltiny_tdsBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtiny_tds:ERROR:Failedtobuildgemnativeextension.完整日志如下:/System

  10. ruby - 如何让几条 haml 线出现在同一行上? - 2

    我有以下haml:9%strongAskedby:10=link_to@user.full_name,user_path(@user)11.small="(#{@question.created_at.strftime("%B%d,%Y")})"这当前将链接和日期放在不同的行上,当它看起来像“链接(日期)”并且日期的类跨度为小...... 最佳答案 您的代码将生成类似这样的html:Askedby:UsernameApril26,2011当您使用类似.small的东西(即使用点而不指定元素类型)时,haml会创建一个implicit

随机推荐