Hi!

Robert Schulz wrote:
> 1) Where are all the queries from?
> ----------------------------------

Spec compliance :-)

> 
> I code a very simple bean with 2 CMP managed fields (the Ship bean from ch5
> in RMH). The following code
> 
> code: ...
> code:   Ship s = home.findByPrimaryKey(pk);
> code:   System.out.println(s.getPrimaryKey() + s.getName() + s.getCode());
> code:   ...
> 
> works but produces the following SQL queries (from the postgres log):
> 
> query: SELECT COUNT(*) FROM ShipBean WHERE id=2

fBPK must validate that the pk exists.

> query: SELECT tonnage,capacity,name,id FROM ShipBean WHERE id=2

ejbLoad is called since you are accessing the instance.

> query: UPDATE ShipBean SET tonnage=80000.0,capacity=3000,name='Utopia',id=2
> WHERE id=2

You are calling s.getName() which starts a new transaction. At end of
transaction state is synched back by storing it. You may not change the
bean state in s.getName() but we don't know that.

> query: UPDATE ShipBean SET tonnage=80000.0,capacity=3000,name='Utopia',id=2
> WHERE id=2

Same as above but for s.getCode().

> The first query is useless - if it is a PK values lookup, it should only
> come back with 0 or 1.

This is for checking existence.

> The second query is what's needed. 

Yup, the load.

> Where are the queries 3 and 4 from? 

State synchronization.

> There
> is no set called
> anywhere in my code at all - in fact the output in the code above is all the
> app is doing.

Yup, seems ok.

> It get's worse when looking at finder methods which return collections. Here
> is an example:
> 
> code: ...
> code:   Collection c = home.findByCapacity(3000);
> code: ... looping over collection, narrowing of each item to s, and
> code:   System.out.println(s.getPrimaryKey() + s.getName() + s.getCode());
> code:   ...
> 
> agains works as described, but the queries generated are:
> 
> query: SELECT id FROM ShipBean WHERE capacity=3000
> query: SELECT tonnage,capacity,name,id FROM ShipBean WHERE id=1
> query: UPDATE ShipBean SET
> tonnage=100000.0,capacity=3000,name='Paradise',id=1 WHERE id=1
> query: UPDATE ShipBean SET
> tonnage=100000.0,capacity=3000,name='Paradise',id=1 WHERE id=1
> query: SELECT tonnage,capacity,name,id FROM ShipBean WHERE id=2
> query: UPDATE ShipBean SET tonnage=80000.0,capacity=3000,name='Utopia',id=2
> WHERE id=2
> query: UPDATE ShipBean SET tonnage=80000.0,capacity=3000,name='Utopia',id=2
> WHERE id=2
> 
> In other words 1 + 3*#elements in collection. For any real app, this will
> kill your database.

Yup, indeed.

> I am particularly interested where the UPDATES are coming from.
> The way this should work is ONE query
> 
>  SELECT * FROM ShipBean WHERE capacity = 3000
> 
> and then a loop over the result set to populate the objects. I can see why
> for large collections
> pulling all the ids in first and then objects by id might be better, but one
> should be able
> to control this behaviour in jaws.xml.
> 
> Any comments anyone? Am I doing stuff wrong?

Yes, you are doing stuff wrong :-) First of all, you are doing the
number one mistake that EJB newbies do: have the client call getX for
all fields. This will create one transaction for each call, and also a
remote call to the bean. The proper way is to either use a bulk data
accessor in the bean, or use a session which extracts the data in one
call. This is the main problem with your code.

The rest is just settings. By default our container complies with the
EJB specification. This isn't very optimized though, as you have
noticed. To fix this you can turn on "tuned updates" by changing
/conf/default/standardjaws.xml: set "tuned-updated" to "true". This will
check if state has changed, and do not store if nothing has changed.
This will remove all UPDATE calls above.

There are more optimizations to be done here (on our behalf), but this
should make things substantially better anyway.

> 2) Complex Finder Problem
> -------------------------
> 
> Also defined a non-standard query method in the home interface
> 
> code: public Collection findCapacityAndName(int capacity, String name)
> code:                                        throws RemoteException,
> FinderException;
> 
> and added a jaws.xml as explained on the web site:
> 
> deploy:<jaws>
> deploy:  <enterprise-beans>
> deploy:    <entity>
> deploy:      <ejb-name>ShipBean</ejb-name>
> deploy:      <finder>
> deploy:        <name>findCapacityAndName</name>
> deploy:        <query>capacity = {0} AND name = {1}</query>
> deploy:        <order>name DESC</order>
> deploy:      </finder>
> deploy:    </entity>
> deploy:  </enterprise-beans>
> deploy:</jaws>
> 
> but the query generated when calling the method is
> 
> query: SELECT id,name DESC FROM ShipBean WHERE capacity = 3000 AND name =
> 'Utopia' ORDER BY name DESC
> 
> Pretty close, but not quite. What am I doing wrong? Is this a bug?

Don't follow. What is the problem?

/Rickard

-- 
Rickard �berg

Email: [EMAIL PROTECTED]
http://www.telkel.com
http://www.jboss.org
http://www.dreambean.com


--
--------------------------------------------------------------
To subscribe:        [EMAIL PROTECTED]
To unsubscribe:      [EMAIL PROTECTED]
Problems?:           [EMAIL PROTECTED]

Reply via email to