db-torque-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Thomas Fischer <tfisc...@apache.org>
Subject Re: silent db hit for associated objects
Date Tue, 16 Aug 2005 15:37:56 GMT
Hi Thomas,

thanks for your answer.

On Tue, 16 Aug 2005, Thomas Vandahl wrote:

> Thomas Fischer wrote:
>> On Tue, 2 Aug 2005, Henning P. Schmiedehausen wrote:
>>> Thomas Fischer <fischer@seitenbau.net> writes:
> [...]
>> Hm, personally, I always use torque.objectIsCaching = true. The reason is 
>> as follows: In most applications, I need transaction safety. Then, I like 
>> to separate the application into a data accesss layer and the presentation 
>> layer. But the presentation layer should be able to retrieve associated 
>> objects, in the bookstore example this would be e.g. to be able to ask a 
>> book for its author. If I want to make this transaction safe and would have 
>> set torque.objectIsCaching to false, then I would have to pass the database 
>> connection to the presentation layer, which is not what a presentation 
>> layer is about.
>
> If I use the getXXX methods without a connection parameter, the expected 
> behaviour from my point of view *is* a DB-hit.

No it is not, if you accept that one may want to cache a whole tree of 
objects. Imagine the following: I have loaded an Author ant his 
corresponding books in a transaction-safe manner, and stored the author 
somewhere (e.g in a Http session). Knowing that the associated books will 
also be stored with the author, I do not store them separately. (ok, for a 
single Author, it would be feasible to store his books separately, but 
consider a lost of authors and their associated books). Then I commit the 
transaction, and I know that all data I have in memory is consistent.

Some time after that I want to access the data I have stored, e.g. because 
the user has submitted a command in an HTML form to change the data. The 
only "official" (i.e. automatically generated) way to get the cached Books 
from an author is to use author.getBooks(). But I care about the data 
being consistent, so in no circumstances do I want to access the database, 
because this would break transaction safety and lead to inconsistent data 
if soneone elase has changed the data in the menatime. Especially, if, by 
some mistake, I did forget to read the books of an author, I want to know 
it. A logical way of knowing is that author.getBooks() returns null.

So in this scenario, the automatic db hit is very contraproductive, and 
there is no easy means to prevent it.

> It is more questionable 
> whether the implicit caching of the collections or related objects is a good 
> idea at all. It hurts especially when using managers.

Then you should consider to set the generator property 
torque.objectIsCaching to false.

>
> I guess that getXXX(Connection con) would be a good extension anyway, because 
> it makes the set of methods more logical. This way, you can always collect 
> your data in a transaction and provide it to the presentation layer in the 
> context separately (we talk Velocity here, don't we? :-)

I am personally using xslt, but that does not play any role. The problem 
is that I have no idea to provide the methods when managers are turned on. 
The implementation without the connection asks the manager to provide the 
object, and there is no way I have found to tell the manager "get that 
object, but if it is not there, use the provided connection". So I did not 
implement it in objectWithManager.vm. Do you have any idea of how to solve 
this one ?

>
>>>> 3) add a generator property torque.silentDbFetch, which is true by 
>>>> default.
>>>> If set to false, the getXXX() methods without arguments will not access 
>>>> the
>>>> db silently, but return null if the associated objects has not been read
>>>> yet. Also, the method does not throw a Torque exception any more (which 
>>>> is
>>>> the main reason why using these methods is more convenient than
>>>> getXXX(boolean silentDbFetch) with silentDbFetch set to false).
>
> Personally, I don't see that you gain much with this. As I understand it, 
> this means that you need to prefetch all related objects in the business code 
> in a transaction like
>
> 	Book b = BookPeer.retrieveByPK(id, con);
> 	b.getAuthor(con);
> 	context.put("book", b);
>
> and then use
>
> 	$book.Author
>
> in the presentation layer. Is that the case?

If you transfer it to java, yes. I would explicitly use book.getAuthor()
in the presentation layer.

> I consider this difficult to 
> read. You need to know that there is something cached under the hood to 
> understand what's going on here...

I would not think so. If one knows that the property 
torque.objectIsCaching exists, in the generator, and one decides not to 
set it to false, one explicitly wants to have the caching. And if one has 
it, is it not legimite to say "I only want to use the cached data, and not 
hit the database"

>
> I kindly ask you to sleep over it again.

One does not have to use it. It is not the default 
behaviour we are talking about (this will stay as it is, of course) but a 
decision you can take if you know what you are doing.

I would agree that if you have uncritical data you would not use it, but 
for critical data it is an absolute nightmare to have uncontrolled access 
to a database outside of transaction. Imaginge having to find an error in 
an application which has a problem like that ! Huh, it makes me shudder...

Thomas

---------------------------------------------------------------------
To unsubscribe, e-mail: torque-dev-unsubscribe@db.apache.org
For additional commands, e-mail: torque-dev-help@db.apache.org


Mime
View raw message