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.

Reply via email to