Re: How to program against the ODMG personality correctly?

2004-01-13 Thread Philippe Hacquin
Sean Dockery wrote:
Hello, Philippe.

Thanks for the analysis and tip about the performance of ODMG in relation
to caching objects.  That is helpful.
I have a question for you about your little snippet...


   PersistenceBroker broker = ((TransactionImpl) tx).getBroker();
   A aDummyObject = new A();
   aDummyObject.setId(id);
   Query qry = new QueryByIdentity(aDummyObject);
   A result = (A) broker.getObjectByQuery(qry);


On the OJB web site, it shows the following usage.

PersistenceBroker broker = ((HasBroker) tx).getBroker();

The use of "HasBroker" seems cleaner than "TransactionImpl" to me.  I know
that since 0.9.8 that classes have disappeared.  :-(  (I'm working on an
application that uses a closed-source third party library based on OJB
0.9.8; I know that classes have disappeared because I couldn't run the
application with OJB 1.0.)
I agree with you. If it's written in the docs, there are more chances 
that the HasBroker interface will be upward compatible, compared to the 
TransactionImpl class.

You could also do this instead...

Identity identity = new Identity(aDummyObject);
A result = (A) broker.getObjectByIdentity(identity);
Is there any difference in behaviour betwen "getObjectByQuery" and
"getObjectByIdentity" when it comes to caching?  Or is it just a style
(using query vs. identity) preference?
You mean:

Identity identity = new Identity(aDummyObject,broker)

?

I think you are right. Looking back at the PersistenceBrokerImpl source 
code, it looks like getObjectByIdentity() is more efficient than 
getObjectByQuery().
I tried to avoid the PB API and stick to the ODMG, until I ran into 
performance problems and struggled to make a better use of the cache, 
that's why I may not use the PB at best.

One more thought: use of the default cache is great, as long as there is 
no external process making changes in the database, outside of this 
instance of OJB, which is the case in my app. But if this is not the 
case (a web app deployed in a cluster without a distributed cache,...), 
the default behavior of the ODMG queries looks good to me: the DB is 
checked to make sure there has not been a modification in the data.

Thanks again, Philippe.  I look forward to your reply.
You are welcome, I like such profitable exchanges of views.



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: How to program against the ODMG personality correctly?

2004-01-13 Thread Sean Dockery
Hello, Philippe.

Thanks for the analysis and tip about the performance of ODMG in relation
to caching objects.  That is helpful.

I have a question for you about your little snippet...

> PersistenceBroker broker = ((TransactionImpl) tx).getBroker();
> A aDummyObject = new A();
> aDummyObject.setId(id);
> Query qry = new QueryByIdentity(aDummyObject);
> A result = (A) broker.getObjectByQuery(qry);

On the OJB web site, it shows the following usage.

PersistenceBroker broker = ((HasBroker) tx).getBroker();

The use of "HasBroker" seems cleaner than "TransactionImpl" to me.  I know
that since 0.9.8 that classes have disappeared.  :-(  (I'm working on an
application that uses a closed-source third party library based on OJB
0.9.8; I know that classes have disappeared because I couldn't run the
application with OJB 1.0.)

You could also do this instead...

Identity identity = new Identity(aDummyObject);
A result = (A) broker.getObjectByIdentity(identity);

Is there any difference in behaviour betwen "getObjectByQuery" and
"getObjectByIdentity" when it comes to caching?  Or is it just a style
(using query vs. identity) preference?

Thanks again, Philippe.  I look forward to your reply.

"Philippe Hacquin" <[EMAIL PROTECTED]> wrote in message
news:[EMAIL PROTECTED]
> Hi Sean,
>
> I'm not an OJB-ODMG expert, but maybe I can help
>
> Sean Dockery wrote:
> > [...]
> >>1) The exception handling code is omitted from the examples for the
sake
> >  of brevity.  Is the manner in which I'm handling exceptions correct?
>
> Take care of the following:
>
>  Transaction tx = implementation.newTransaction();
>  tx.begin();
>  try
>  {
>  
>  tx.commit();
>  }
>  catch (Throwable t)
>  {
>  tx.abort();
>  throw new DaoException(t);
>  }
> You may catch a TransactionAbortedException, which in this case will
> leave tx null, thus you will end with a NPE if you execute tx.abort()
>
>
> >>
> >>2) I've written my retrieval routine to use a persistence broker query.
> >>Using persistence broker queries in this manner is apparently faster.
In
> > a reply in another thread, I read...
> >>
> >>"Philippe Hacquin" <[EMAIL PROTECTED]> wrote in message
> >>news:<[EMAIL PROTECTED]>...
> >>
> >>>... and they are much more efficient, too, because they use the cache.
> >>
> >>This confuses me somewhat.  Does this mean that the ODMG personality of
> > OJB doesn't use caching?  Or do OQL queries bypass caching?
>
> I've recently made some performance tests, with p6spy and network traces
> to monitor the queries sent to the database. I am using ODMG in OJB 1.0
> RC4, too.
> Say you have a class A that has some properties, with at least the "id"
> property which is mapped to the primary key of your table (hence, you
> don't use anonymous keys).
> You want to get a reference to a persistent object using the id. So you
> write an OQL query like "select anInstance from " + A.class.getname() +
> "where id = \"" + id + "\""
> Well, you have to know this ODMG query will lead to a straight SQL query
> to the database, even if the object is already in the cache. But the
> cache will anyway be looked up after the SQL query, to check if the
> materialization process can be avoided. This process consumes some time,
> you can check that during some tests. So an ODMG query uses the cache,
> but does not use at 100%.
> To use the cache in an effectively manner, you have to use a PB query
> against the object Identity (well, this is what I deducted, if there is
> a more efficient way to do it with the default cache, I'd like to hear
> about it).
> This is the way I code it:
>
> PersistenceBroker broker = ((TransactionImpl) tx).getBroker();
> A aDummyObject = new A();
> aDummyObject.setId(id);
> Query qry = new QueryByIdentity(aDummyObject);
> A result = (A) broker.getObjectByQuery(qry);
>
> This way the cache is looked up _before_ querying the DB.
> This was not obvious when I began using OJB, but should have if I had
> carefully read the "Object cache" documentation: the lookup() method
> takes an Identity instance as search key in the cache.
> Well, I supposed this was handled transparently in the ODMG
> implementation layer...
>
> HTH




-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: How to program against the ODMG personality correctly?

2004-01-11 Thread Philippe Hacquin
Hi Sean,

I'm not an OJB-ODMG expert, but maybe I can help

Sean Dockery wrote:
[...]
1) The exception handling code is omitted from the examples for the sake
 of brevity.  Is the manner in which I'm handling exceptions correct?
Take care of the following:

Transaction tx = implementation.newTransaction();
tx.begin();
try
{

tx.commit();
}
catch (Throwable t)
{
tx.abort();
throw new DaoException(t);
}
You may catch a TransactionAbortedException, which in this case will 
leave tx null, thus you will end with a NPE if you execute tx.abort()


2) I've written my retrieval routine to use a persistence broker query.
Using persistence broker queries in this manner is apparently faster.  In
a reply in another thread, I read...
"Philippe Hacquin" <[EMAIL PROTECTED]> wrote in message
news:<[EMAIL PROTECTED]>...
... and they are much more efficient, too, because they use the cache.
This confuses me somewhat.  Does this mean that the ODMG personality of
OJB doesn't use caching?  Or do OQL queries bypass caching?
I've recently made some performance tests, with p6spy and network traces 
to monitor the queries sent to the database. I am using ODMG in OJB 1.0 
RC4, too.
Say you have a class A that has some properties, with at least the "id" 
property which is mapped to the primary key of your table (hence, you 
don't use anonymous keys).
You want to get a reference to a persistent object using the id. So you 
write an OQL query like "select anInstance from " + A.class.getname() + 
"where id = \"" + id + "\""
Well, you have to know this ODMG query will lead to a straight SQL query 
to the database, even if the object is already in the cache. But the 
cache will anyway be looked up after the SQL query, to check if the 
materialization process can be avoided. This process consumes some time, 
you can check that during some tests. So an ODMG query uses the cache, 
but does not use at 100%.
To use the cache in an effectively manner, you have to use a PB query 
against the object Identity (well, this is what I deducted, if there is 
a more efficient way to do it with the default cache, I'd like to hear 
about it).
This is the way I code it:

   PersistenceBroker broker = ((TransactionImpl) tx).getBroker();
   A aDummyObject = new A();
   aDummyObject.setId(id);
   Query qry = new QueryByIdentity(aDummyObject);
   A result = (A) broker.getObjectByQuery(qry);
This way the cache is looked up _before_ querying the DB.
This was not obvious when I began using OJB, but should have if I had 
carefully read the "Object cache" documentation: the lookup() method 
takes an Identity instance as search key in the cache.
Well, I supposed this was handled transparently in the ODMG 
implementation layer...

HTH

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: How to program against the ODMG personality correctly?

2004-01-10 Thread Sean Dockery
I posted this right around new years, but I have not seen any responses
since then and some of these questions are still eating at me.  Can anyone
provide any answers to some of the questions that I've asked?

Thanks in advance.

"Sean Dockery" <[EMAIL PROTECTED]> wrote in message
news:[EMAIL PROTECTED]
> Hello there.
>
> I'm fairly new to OJB.  I've read several of the tutorials and I'm
working
> on creating an application from scratch.
>
> Below are three classes that I wrote.  One is my DAO class, the second
class
> is an inversion-of-control interface that I'm using to populate the
object
> after locking it in the DAO class, and the last class is a Struts action
> which using the DAO class and provides an implementation of the
> UserConfigurator interface.
>
> I was wondering if anyone could provide some feedback and opinions about
the
> code.  I'm mainly curious about the following:
>
> 1) The exception handling code is omitted from the examples for the sake
of
> brevity.  Is the manner in which I'm handling exceptions correct?
>
> 2) I've written my retrieval routine to use a persistence broker query.
> Using persistence broker queries in this manner is apparently faster.  In
a
> reply in another thread, I read...
>
> "Philippe Hacquin" <[EMAIL PROTECTED]> wrote in message
> news:<[EMAIL PROTECTED]>...
> > ... and they are much more efficient, too, because they use the cache.
>
> This confuses me somewhat.  Does this mean that the ODMG personality of
OJB
> doesn't use caching?  Or do OQL queries bypass caching?
>
> 3) I've chose to perform object deletion using the persistence broker
> instead of database.deletePersistent.  What is the consequence of using
one
> over the other?
>
> 4) The PB transaction mechanism uses database locks.  The ODMG
personality
> uses object locks.  Yet, the ODMG personality is less performant than the
PB
> personality (according to the performance page on the web site.)  Last
time
> I checked, memory operations were less expensive than database I/O--so I
> would have expected ODMG to out-perform PB.  Can anyone explain this
> apparent contradiction?
>
> 5) I've seen an application that uses OJB that performs updates directly
> against the database using JDBC.  I suspect that the implication is that
> cached objects can become out of sync with data in the database.  Does
OJB
> have a means by which to detect that a row has been changed by another
user?
>
> 6) The auto-retrieve attribute must (apparently) be set to true for ODMG.
> This seems a little evil in that I will always be retrieving a graph of
> objects instead of the single object in which I'm interested.  The
> application mentioned in question 5 has severe performance problems
related
> to database access; I suspect that the root of the performance problems
are
> being caused by having auto-retrieve set to true for several key entities
in
> the application.  What happens to the behaviour of the ODMG
implementation
> if auto-retrieve is set to false?  (It suggests that this is a no-no on
the
> web site, but doesn't elaborate on what problems will arise.)  Should I
be
> switching to the PB personality of OJB to avoid problems?
>
> 7) Why would I choose to use the ODMG personality over the PB
personality?
> I've seen some (rather unhelpful) replies saying "it depends on your
needs"
> and I'm looking for something a little more insightful.  What does using
the
> ODMG personality get me?  (I'm not sure what "real Object Transactions"
are
> supposed to be, but that is one of the reasons cited on the web site.)
>
> Thanks very much for your precious time.  It is greatly appreciated.
>
> UserDao.java:
> package catalyst.dao;
> import org.apache.ojb.broker.PersistenceBroker;
> import org.apache.ojb.broker.query.Criteria;
> import org.apache.ojb.broker.query.Query;
> import org.apache.ojb.broker.query.QueryFactory;
> import org.apache.ojb.odmg.HasBroker;
> import org.apache.ojb.odmg.OJB;
> import org.odmg.Implementation;
> import org.odmg.Transaction;
> import catalyst.domain.User;
> public class UserDao {
> private static UserDao instance = new UserDao();
> private UserDao() {
> }
> public static UserDao getInstance() {
> return instance;
> }
> private User findUser(Integer userId) throws DaoException {
> Implementation odmg = OJB.getInstance();
> Transaction tx = odmg.newTransaction();
> tx.begin();
> try {
> PersistenceBroker broker = ((HasBroker) tx).getBroker();
> Criteria criteria = new Criteria();
> criteria.addEqualTo("userId", userId);
> Query query = QueryFactory.newQuery(User.class, criteria);
> User user = (User) broker.getObjectByQuery(query);
> tx.commit();
> return user;
> }
> catch (Throwable t) {
> tx.abort();
> throw new DaoException(t);
> }
> }
> private void storeUser(User user, UserConfigurator configurator) throws
> DaoException {
> Implementation implementation = OJB.getInstance();
> Transaction tx = implementation.newTransaction();
> tx.begin();
> try {
> tx.lock(user, Transaction.WRITE);
> configu

How to program against the ODMG personality correctly?

2004-01-02 Thread Sean Dockery
Hello there.

I'm fairly new to OJB.  I've read several of the tutorials and I'm working
on creating an application from scratch.

Below are three classes that I wrote.  One is my DAO class, the second class
is an inversion-of-control interface that I'm using to populate the object
after locking it in the DAO class, and the last class is a Struts action
which using the DAO class and provides an implementation of the
UserConfigurator interface.

I was wondering if anyone could provide some feedback and opinions about the
code.  I'm mainly curious about the following:

1) The exception handling code is omitted from the examples for the sake of
brevity.  Is the manner in which I'm handling exceptions correct?

2) I've written my retrieval routine to use a persistence broker query.
Using persistence broker queries in this manner is apparently faster.  In a
reply in another thread, I read...

"Philippe Hacquin" <[EMAIL PROTECTED]> wrote in message
news:<[EMAIL PROTECTED]>...
> ... and they are much more efficient, too, because they use the cache.

This confuses me somewhat.  Does this mean that the ODMG personality of OJB
doesn't use caching?  Or do OQL queries bypass caching?

3) I've chose to perform object deletion using the persistence broker
instead of database.deletePersistent.  What is the consequence of using one
over the other?

4) The PB transaction mechanism uses database locks.  The ODMG personality
uses object locks.  Yet, the ODMG personality is less performant than the PB
personality (according to the performance page on the web site.)  Last time
I checked, memory operations were less expensive than database I/O--so I
would have expected ODMG to out-perform PB.  Can anyone explain this
apparent contradiction?

5) I've seen an application that uses OJB that performs updates directly
against the database using JDBC.  I suspect that the implication is that
cached objects can become out of sync with data in the database.  Does OJB
have a means by which to detect that a row has been changed by another user?

6) The auto-retrieve attribute must (apparently) be set to true for ODMG.
This seems a little evil in that I will always be retrieving a graph of
objects instead of the single object in which I'm interested.  The
application mentioned in question 5 has severe performance problems related
to database access; I suspect that the root of the performance problems are
being caused by having auto-retrieve set to true for several key entities in
the application.  What happens to the behaviour of the ODMG implementation
if auto-retrieve is set to false?  (It suggests that this is a no-no on the
web site, but doesn't elaborate on what problems will arise.)  Should I be
switching to the PB personality of OJB to avoid problems?

7) Why would I choose to use the ODMG personality over the PB personality?
I've seen some (rather unhelpful) replies saying "it depends on your needs"
and I'm looking for something a little more insightful.  What does using the
ODMG personality get me?  (I'm not sure what "real Object Transactions" are
supposed to be, but that is one of the reasons cited on the web site.)

Thanks very much for your precious time.  It is greatly appreciated.

UserDao.java:
package catalyst.dao;
import org.apache.ojb.broker.PersistenceBroker;
import org.apache.ojb.broker.query.Criteria;
import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.query.QueryFactory;
import org.apache.ojb.odmg.HasBroker;
import org.apache.ojb.odmg.OJB;
import org.odmg.Implementation;
import org.odmg.Transaction;
import catalyst.domain.User;
public class UserDao {
private static UserDao instance = new UserDao();
private UserDao() {
}
public static UserDao getInstance() {
return instance;
}
private User findUser(Integer userId) throws DaoException {
Implementation odmg = OJB.getInstance();
Transaction tx = odmg.newTransaction();
tx.begin();
try {
PersistenceBroker broker = ((HasBroker) tx).getBroker();
Criteria criteria = new Criteria();
criteria.addEqualTo("userId", userId);
Query query = QueryFactory.newQuery(User.class, criteria);
User user = (User) broker.getObjectByQuery(query);
tx.commit();
return user;
}
catch (Throwable t) {
tx.abort();
throw new DaoException(t);
}
}
private void storeUser(User user, UserConfigurator configurator) throws
DaoException {
Implementation implementation = OJB.getInstance();
Transaction tx = implementation.newTransaction();
tx.begin();
try {
tx.lock(user, Transaction.WRITE);
configurator.configure(user);
tx.commit();
}
catch (Throwable t) {
tx.abort();
throw new DaoException(t);
}
}
public void createUser(UserConfigurator configurator) throws DaoException {
storeUser(new User(), configurator);
}
public void updateUser(Integer userId, UserConfigurator configurator) throws
DaoException {
storeUser(findUser(userId), configurator);
}
public void deleteUser(Integer userId) throws DaoException {
Implementation odmg = OJB.getInstance();
Transaction tx = odmg.newTransaction();
tx.begin