【问题标题】:Hibernate: how to handle 'saving' a transient object that may or may not exist in the databaseHibernate:如何处理“保存”数据库中可能存在或不存在的瞬态对象
【发布时间】:2012-03-14 23:27:59
【问题描述】:

这是一个关于持久化我的数据库中可能已经存在的瞬态对象的 Hibernate 问题。

给定一个临时对象(Id 为空),它可能已经存在也可能不存在于我的数据库中,并且它也有一个唯一列(即我的业务主键,它带有'unique=true' 注释)。我如何尝试保存它而不会有出现错误的风险:完整性约束违规:唯一约束或索引违规

在尝试持久化对象之前,我应该提供检查数据库是否存在重复项的方法吗?这有点令人沮丧。

这是我为尝试保存两个相同的瞬态对象而执行的测试...

这是我的对象:

@Entity
public class ArchivedLicence extends DomainObject implements Licence {
    private static final long serialVersionUID = 84973741L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;


    @Column (unique=true, nullable=false)
    private String md5Hash;

    @Override
    public boolean equals(Object o) {
        if(o instanceof ArchivedLicence) {
            return md5Hash.equals(((ArchivedLicence)o).md5Hash);
        }
        return super.equals(o);
    }
    ...

这是我的数据访问对象中的保存方法:

    @Transactional
    @Override
    public void saveOrUpdate(ArchivedLicence archivedLicence) {

        getCurrentSession().saveOrUpdate(archivedLicence);
        //getCurrentSession().save(archivedLicence);
    }

这是我的测试:

        //Given the first ArchivedLicence
        ArchivedLicence archivedLicence1 = null;
        try {
            archivedLicence1 = new ArchivedLicence(licenceDao.getByName(internalLicenceName));
        } catch (IOException ex) {
            Logger.getLogger(OrderTest.class.getName()).log(Level.SEVERE, null, ex);
        }

        //When it is persisted
        archivedLicenceDao.saveOrUpdate(archivedLicence1);
        flush();

        //Then there should be one ArchivedLicence in the the database
        assertEquals(new Long(1), archivedLicenceDao.countAll());

        //When a second identical ArchiviedLicence is persisted
        ArchivedLicence archivedLicence2 = null;
        try {
            archivedLicence2 = new ArchivedLicence(licenceDao.getByName(internalLicenceName));
        } catch (IOException ex) {
            Logger.getLogger(OrderTest.class.getName()).log(Level.SEVERE, null, ex);
        }
        archivedLicenceDao.saveOrUpdate(archivedLicence2);
        flush();

        //Then there should still only be one ArchivedLicence in the database
        assertEquals(new Long(1), archivedLicenceDao.countAll());

任何帮助表示感谢,谢谢,乔恩

【问题讨论】:

  • 您可以执行保存并刷新并捕获异常吗?

标签: hibernate transient


【解决方案1】:

不幸的是,您将不得不查询数据库以查看对象是否存在,如果存在则更新它,如果不存在则保存一个新对象。

saveOrUpdate 不是为了这个目的——它的作用是检查内存中对象的 id,如果 id 为 null,则调用 save,如果 id 不为 null,则更新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-03
    • 1970-01-01
    • 2011-01-19
    • 2014-10-26
    • 2014-05-16
    相关资源
    最近更新 更多