From: Gavin_King/Cirrus%<CI...@ci...> - 2002-03-01 08:31:48
|
> Before I go on, I want to make sure my terminology is > right. A persistent object is an object that gets > instantiated by calling Session.create(Class) and a > transient object is one created the normal way using > new. yes. Note, using create is (as of 0.9.7) no longer advantageous. its just as good to use: Foo foo = new Foo(); session.save(foo); And, in fact, this approach will sometimes be more efficient. You can now view create() as just a shortcut way of expressing the previous two lines. > Session session = ...; > Receipt receipt = > (Receipt)session.create(Receipt.class); > Product p = (Product)session.load(Product.class, new > Long(0)); > LineItem item = new LineItem(); > item.setProduct(p); > item.setQuantity(3); > receipt.addLineItem(item); > session.commit(); > Receipt contains a List of LineItem. This list is > declared in the xml, but hibernate runtime does not > persist the transient object. Is this a feature or a > bug? well, depends upon how you view it. Hibernate does *not* presently do persistence by reachability. The reasoning behind this is that *deletion* by reachability is a hard problem for an O-R mapping layer. You could try to use reference counting, but then the reference count would need to be kept in the db. (And reference counting is dodgy if you have circular references). You could try to use mark-and-sweep but the performance cost would be prohibitive. What will be implemented in a future version (Daniel has volunteered to implement this) is a "dependent" attribute in the mapping descriptor that causes saves and deletes to be cascaded. I strongly believe this to be the best solution. For now, the following code will do what you want: Session session = ...; Receipt receipt = (Receipt)session.create(Receipt.class); Product p = (Product)session.load(Product.class, new Long(0)); LineItem item = (LineItem) session.create(LineItem.class); item.setProduct(p); item.setQuantity(3); receipt.addLineItem(item); session.commit(); (Thats a 1/2 line change) Remember to explicity delete the lineitem when you delete the owning product. You can cascade deletions manually from PersistentLifecycle.delete(), if you don't want to pollute the application logic. You will be able to do it your way as soon as Daniel gets back to us ;) |