jjzjj

java - Hibernate saveOrUpdate() 尝试在应该更新时保存

coder 2024-03-26 原文

我有一个名为 IssueParticipant 的 Hibernate 实体。它基本上描述了用户和问题(类似于 JIRA 或 Bugzilla 问题)之间的关系。它代表数据库中的一种多对多链接表,将用户 ID 链接到问题 ID,但还包括与通知设置相关的其他信息,因此将其视为自己的实体。

我在使用 userId 和 issueId 作为复合键时遇到了很大的问题,所以我创建了一个合成键,它是一个字符串(在 postgres 数据库中是一个 varchar),其格式如下:_。

现在,我有一个屏幕,用户可以在其中编辑与问题关联的所有用户,同时还可以编辑通知设置。在 Controller 类中,我创建了一个 IssueParticipants 列表,如下所示:

IssueParticipant participant = new IssueParticipant();
participant.setUser(accountUser);
participant.setIssue(issue);

因此,此时这些当然不由 Hibernate 管理。

然后在我的 DAO 中,我遍历它们并调用 saveOrUpdate(),期望如果数据库中存在具有相同合成键的 IssueParticipant,它将更新;否则它将被插入:

    for (IssueParticipant participant : participants) {
        getCurrentSession().saveOrUpdate(participant);
        savedIds.add(participant.getIssueUserKey());
    }

(savedIds 是我正在维护的一个列表,这样我以后就会知道我应该从数据库中删除哪些 IssueParticipants)。

不过,我得到的不是我所期望的,而是一个异常:

org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "issue_participant_pkey"

这是我的实体类,缩写为:

public class IssueParticipant extends Entity {

    private String issueUserKey;
    private Long issueId;
    private Long userId;

     // Edit: adding 'dateAdded' definition
    private Date dateAdded;
// ...

    // below may be null
    private SPUser user;
    private Issue issue;

    public static IssueParticipant nulledIssueParticipant() {
        IssueParticipant ip = new IssueParticipant();
        return ip;
    }
    public String getIssueUserKey() {
        return issueUserKey;
    }

    public void setIssueUserKey(String issueUserKey) {
        this.issueUserKey = issueUserKey;
    }

    public Long getId() {
        // currently meaningless
        return 0L;
    }

    public Long getIssueId() {
        return this.issueId;
    }

    public void setIssueId(Long issueId) {
        this.issueId = issueId;
        updateKey();
    }

    public Long getUserId() {
        return this.userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
        updateKey();
    }

    private void updateKey() {
        issueUserKey = getIssueId() + KEY_SEP + getUserId();
    }

    public SPUser getUser() {
        return user;
    }

    public void setUser(SPUser user) {
        this.user = user;
        setUserId(user.getId());
    }

    public Issue getIssue() {
        return issue;
    }

    public void setIssue(Issue issue) {
        this.issue = issue;
        setIssueId(issue.getId());
    }

// edit: adding 'dateAdded' methods
public Date getDateAdded() {
    return dateAdded;
}

public void setDateAdded(Date dateAdded) {
    this.dateAdded = dateAdded;
}

...

}

这是它的 hbm 文件:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping default-lazy="false">
    <class name="com.xxx.yyy.IssueParticipant" table="issue_participant">
        <id name="issueUserKey" column="issue_user_key" type="string">
            <generator class="assigned"/>
        </id> 
        <version name="dateAdded" column="date_added" type="timestamp" unsaved-value="null" />
        <property name="issueId" column="issue_id" />
        <many-to-one name="user" column="user_id" class="com.xxx.yyy.SPUser" not-null="true" cascade="none" />
        <property name="alertRss" column="alert_rss" type="boolean" />
        <property name="alertEmail" column="alert_email" type="boolean" />
        <property name="alertWeb" column="alert_web" type="boolean" />
        <property name="alertClient" column="alert_client" type="boolean" />

    </class>
</hibernate-mapping>

而且确实user_issue_key是相应数据库表中的主键。

我觉得在这种情况下,正确的解决方案可能只是使用 SpringJDBC,但我真的很想弄清楚这里发生了什么。有人有什么想法吗?提前致谢。

最佳答案

saveOrUpdate() 不会查询数据库来决定是保存还是更新给定的实体。它根据实体的状态做出决定,如下所示:

  • if the object is already persistent in this session, do nothing
  • if another object associated with the session has the same identifier, throw an exception
  • if the object has no identifier property, save() it
  • if the object's identifier has the value assigned to a newly instantiated object, save() it
  • if the object is versioned by a <version> or <timestamp>, and the version property value is the same value assigned to a newly instantiated object, save() it
  • otherwise update() the object

因此,据我所知,在您的案例中,决定是基于 dateAdded 字段的值,因此您需要保留它以区分新实例和分离实例。

另请参阅:

关于java - Hibernate saveOrUpdate() 尝试在应该更新时保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10917192/

有关java - Hibernate saveOrUpdate() 尝试在应该更新时保存的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

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

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

  4. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  5. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  6. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  7. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  8. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  9. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  10. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

随机推荐