Hibernate认为持久化类(persistent class)新实例化的对象是瞬时(Transient)的。 我们可通过将瞬时(Transient)对象与session关联而把它变为持久(Persistent)的。
DomesticCat fritz = new DomesticCat(); fritz.setColor(Color.GINGER); fritz.setSex('M'); fritz.setName("Fritz"); Long generatedId = (Long) sess.save(fritz);
如果Cat
的持久化标识(identifier)是generated
类型的, 那么该标识(identifier)会自动在save()
被调用时产生并分配给cat
。 如果Cat
的持久化标识(identifier)是assigned
类型的,或是一个复合主键(composite key), 那么该标识(identifier)应当在调用save()
之前手动赋予给cat
。 你也可以按照EJB3 early draft中定义的语义,使用persist()
替代save()
。
persist()
makes a transient instance persistent. However, it doesn't guarantee that the identifier value will be assigned to the persistent
instance immediately, the assignment might happen at flush time. persist()
also guarantees that it will not execute an INSERT
statement if it is called outside of transaction boundaries. This is useful in long-running conversations with an extended
Session/persistence context.
save()
does guarantee to return an identifier. If an INSERT has to be executed to get the identifier ( e.g. "identity" generator,
not "sequence"), this INSERT happens immediately, no matter if you are inside or outside of a transaction. This is problematic
in a long-running conversation with an extended Session/persistence context.
此外,你可以用一个重载版本的save()
方法。
DomesticCat pk = new DomesticCat(); pk.setColor(Color.TABBY); pk.setSex('F'); pk.setName("PK"); pk.setKittens( new HashSet() ); pk.addKitten(fritz); sess.save( pk, new Long(1234) );
如果你持久化的对象有关联的对象(associated objects)(例如上例中的kittens
集合) 那么对这些对象(译注:pk和kittens)进行持久化的顺序是任意的(也就是说可以先对kittens进行持久化也可以先对pk进行持久化), 除非你在外键列上有NOT NULL
约束。 Hibernate不会违反外键约束,但是如果你用错误的顺序持久化对象(译注:在pk持久化之前持久化kitten),那么可能会违反NOT NULL
约束。
通常你不会为这些细节烦心,因为你很可能会使用Hibernate的 传播性持久化(transitive persistence)功能自动保存相关联那些对象。 这样连违反NOT NULL
约束的情况都不会出现了 - Hibernate会管好所有的事情。 传播性持久化(transitive persistence)将在本章稍后讨论。