I've got an object which contains a collection. When I change the object collection OJB wants to delete the related object in the database. For example I've got a Book object with a collection of Author object. I've got an n:m non decomposed relationship and my descriptor don't allows cascade-delete cascade updates (auto-retrieve="true"/auto-delete="false"/auto-update="false" in my collection descriptor).
If I do this : public void updateBook(Book b, Author newAuthor) { tx.begin(); OQLQuery query = odmg.newOQLQuery(); query.create("select b from " + Book.class.getName() + " where id = " + b.getId(); DList results = (DList) query.execute(); Book myBook = (Book)results.get(0); tx.lock(myBook , Transaction.WRITE); myBook.getAuthors().clear(); myBook.getAuthors().add(newAuthor); tx.commit; } OJB delete the indirection table's related values and ALSO the author table values. If I do this : public void updateBook(Book b, Author newAuthor) { tx.begin(); OQLQuery query = odmg.newOQLQuery(); query.create("select b from " + Book.class.getName() + " where id = " + b.getId(); DList results = (DList) query.execute(); Book myBook = (Book)results.get(0); tx.lock(myBook , Transaction.WRITE); ArrayList authList = new ArrayList(); authList.add(newAuthor); myBook.setAuthors(authList); tx.commit; } OJB delete only the indirection table's related values (which is the expected result). Is it a bug ? Is it a misunderstanding of the framework ? ***************************************************************************************************************************** About using/design (related question) : Generally I want to get a domain (business) object from the persistence layer. Then I use it in my app (webapp), modify it and when modification are validated, update it in the persistent storage. I use a class for persistence actions (CRUD) like this : class BookPersistence { static BookPersistence getInstance() {...} Book getBook(String bookId) { ...} void storeBook(Book b) { ...} void deleteBook(Book b) { ...} void updateBook(Book b) { ...} } And I use it like this : Book b = new Book(); BookPersistence.getInstance().store(b); ... And : Book b1 = BookPersistence.getInstance().getBook("bookID"); b1.setXXX(...); ... BookPersistence.getInstance().updateBook(b1); Whith an update method like this : public void updateBook(Book b) { tx.begin(); tx.lock(myBook , Transaction.WRITE); tx.commit; } It doesn work 'cause book is modified outside the transaction and OJB doesn't "monitor" it (I think). But I can't open a transaction during all the modification time of my object and commit at the end, isn't it ? If I use this object in a webapp (modification by a form), I must wait all the validation (and request, validation, ...) before commiting. It retains lock during this time (even if I use optimistic locking, a long time transaction can desynchronize data with multiple users). And I've got to add Transaction demarcation in my business process code. So I try to declare the object dirty in my transaction like this : public void updateBook(Book b) { tx.begin(); tx.lock(myBook , Transaction.WRITE); ((TransactionImpl)tx).makeDirty(b); tx.commit; } It generally work but not in the case described above (with a collection) : OJB delete related collection object data. And it's not a standardized process (the makeDirty() of TransactionImpl object is not part of ODMG API). If I do this : public void updateBook(Book b) { tx.begin(); OQLQuery query = odmg.newOQLQuery(); query.create("select b from " + Book.class.getName() + " where id = " + b.getId(); DList results = (DList) query.execute(); Book myBook = (Book)results.get(0); tx.lock(myBook , Transaction.WRITE); // I don't think that the following line is usefull 'cause // the OID of Book b is the same than the Book myBook // and this object is monitored due to previous query isn't it ? BeanUtils.copyProperties(b, myBook); tx.commit; } OJB also delete related collection object data (and : b came from a previous select). So what's the solution ? Do I use bad patterns ? Is it a bug ? Am I too stupid (pleeeaaase tell me I'm not) ? Thanks.