代码之家  ›  专栏  ›  技术社区  ›  Stephano

了解Hibernate存储或更新和持久性生命周期

  •  3
  • Stephano  · 技术社区  · 16 年前

    让我们来看一个简单的例子,一只狗和一只猫是朋友。这并不罕见。它还具有比我的商业案例更有趣的好处。

    我们需要一个名为“savefriends”的函数,它有一个狗名和一个猫名。我们先救狗,然后救猫。为了使这个例子有效,猫将有一个对狗的引用。我知道这不是一个理想的例子,但它很可爱,适合我们的目的。

    友好服务.java

    public int saveFriends(String dogName, String catName) {
        Dog fido = new Dog();
        Cat felix = new Cat();
    
        fido.name = dogName;
        fido = animalDao.saveDog(fido);
    
        felix.name = catName;
        [ex.A]felix.friend = fido;
        [ex.B]felix.friend = animalDao.getDogByName(dogName);
        animalDao.saveCat(felix);
    }
    

    Java语言 (扩展休眠的支持)

    public Dog saveDog(Dog dog) {
        getHibernateTemplate().saveOrUpdate(dog);
        return dog
    }
    
    public Cat saveCat(Cat cat) {
        getHibernateTemplate().saveOrUpdate(cat);
        return cat;
    }
    
    public Dog getDogByName(String name) {
        return (Dog) getHibernateTemplate().find("from Dog where name=?", name).get(0);
    }
    

    现在,假设我想使用示例A或示例B来保存我的朋友。一个比另一个好用吗?

    此外,示例B是否会让您遇到臭名昭著的“非空属性引用空值或瞬时值”错误?我只是在猜测,但我认为这是因为这只狗还在训练中。

    如果这两个例子都不起作用,我会理解的,但请解释原因。

    3 回复  |  直到 16 年前
        1
  •  4
  •   Pascal Thivent    16 年前

    现在,假设我想使用示例A或示例B来保存我的朋友。一个比另一个好用吗?

    这两个示例都可以工作(在示例B中,Hibernate将 flush the session before query executions 因此,它将在select之前插入狗),但我看不到在已经有了dog实例的情况下执行额外的select(示例B)的意义。我只想举个例子A。

    此外,示例B是否会让您遇到臭名昭著的“非空属性引用空值或瞬时值”错误?

    不(见上文)。在示例B中,狗不再是短暂的。在示例A中,插入将按正确的顺序进行。

    我只是在猜测,但我认为这是因为这只狗还在训练中。

    第一级缓存(会话)用于按ID查找,这里不是这种情况。

        2
  •  2
  •   Woot4Moo    16 年前

    从位于的文档 hibernate

    saveorupdate()执行以下操作:

    如果对象在此会话中已经是持久的,则不执行任何操作。

    如果与会话关联的另一个对象具有相同的标识符,则引发异常

    如果对象没有标识符属性,则保存()它

    如果对象标识符的值已分配给新实例化的对象,则保存()它。

    如果对象由或进行版本控制,并且version属性值与分配给新实例化对象的值相同,则save()它

    否则,更新()对象

    从性能上讲,如果不打开与数据库的连接,那么为fido指向的对象分配引用会更快。

        3
  •  2
  •   mdma    16 年前

    两者都能正常工作,但效率不一样。在B中,因为它执行一个查询,所以它不仅有查询本身的开销,而且还强制Hibernate刷新对数据库的更改-这些更改可能一直保存在内存中,直到提交事务,并与许多其他更改一起发送。

    到数据库的连接通常具有很高的延迟,因此批处理用于一次发送许多更改,从而减少每个语句的延迟。将变更集分解成许多小的变更,每一条语句的开销比一组大的变更要高。因此,在可能的情况下,最好一起提交所有更改。