I encountered an unexpected query result.
The OQL includes expressions on both the master objects
and the dependent/related objects.

The problem is described below.
I'd like to know whether the result is correct.


<<< Execution Environment >>>
* Castor 1.2
* MySQL 5.0.45
* JDK 1.5.0_14
* Windows XP, SP2


<<< Database Tables (state and city, 1:N) >>>

    CREATE TABLE state
    (
        state_code      char(2)     NOT NULL,
        state_name      char(25)    NOT NULL,
        country_name    char(25)    NOT NULL,

        PRIMARY KEY (state_code)
    );

    CREATE TABLE city
    (
        city_code       char(4)     NOT NULL,
        city_name       char(25)    NOT NULL,
        state_code      char(2)     NOT NULL, /* (FK) */

        PRIMARY KEY (city_code)
    );



<<< Database Records >>>

    mysql> select * from state;
    +------------+----------------------+--------------+
    | state_code | state_name           | country_name |
    +------------+----------------------+--------------+
    | DC         | DISTRICT OF COLUMBIA | USA          |
    | WA         | WASHINGTON           | USA          |
    +------------+----------------------+--------------+
    2 rows in set (0.00 sec)

    mysql> select * from city;
    +-----------+------------+------------+
    | city_code | city_name  | state_code |
    +-----------+------------+------------+
    | WWAS      | WASHINGTON | DC         |
    +-----------+------------+------------+
    1 row in set (0.00 sec)



<<< Castor JDO Mapping (State and City) >>>

    <class name="atis.State" identity="code">
        <cache-type type="unlimited"/>
        <map-to table="state"/>

        <field name="code" type="string">
            <sql name="state_code" type="char"/>
        </field>

        <field name="name" type="string">
            <sql name="state_name" type="char"/>
        </field>

        <field name="countryName" type="string">
            <sql name="country_name" type="char"/>
        </field>

        <field name="cities" type="atis.City" collection="collection">
            <sql many-key="state_code"/>
        </field>
    </class>

    <class name="atis.City" identity="code" depends="atis.State">
        <cache-type type="unlimited"/>
        <map-to table="city"/>

        <field name="code" type="string">
            <sql name="city_code" type="char"/>
        </field>

        <field name="name" type="string">
            <sql name="city_name" type="char"/>
        </field>

        <field name="state" type="atis.State">
            <sql name="state_code"/>
        </field>
    </class>



<<< select-all OQL (NO PROBLEM) >>>
  *** OQL: SELECT State FROM atis.State State

  *** Castor log messages (linebreaks and spaces added):
     DEBUG (PreparedStatementProxy.<init>:77) - 
        Creating prepared statement proxy for SQL statement
        SELECT 
state.state_code,state.state_name,state.country_name,city.city_code
        FROM state LEFT OUTER JOIN city ON state.state_code=city.state_code
     DEBUG (DebuggingCacheProxy.remove:176) - 
        unlimited.remove(atis.State/<DC(2175)>) [atis.State]
     DEBUG (DebuggingCacheProxy.remove:176) - 
        unlimited.remove(atis.City/<WWAS(2677522)>) [atis.City]
     DEBUG (PreparedStatementProxy.<init>:77) - 
        Creating prepared statement proxy for SQL statement 
        SELECT city.city_code,city.city_name,city.state_code 
        FROM city 
        WHERE city.city_code=?
     DEBUG (DebuggingCacheProxy.remove:176) - 
        unlimited.remove(atis.State/<WA(2762)>) [atis.State]
     DEBUG (ConnectionProxy.invoke:71) - Committing JDBC Connection instance.
     DEBUG (ConnectionProxy.invoke:69) - Closing JDBC Connection instance.
     DEBUG (DebuggingCacheProxy.put:167) - 
        unlimited.put(atis.City/<WWAS(2677522)>,
        [EMAIL PROTECTED]) [atis.City]
     DEBUG (DebuggingCacheProxy.put:167) - 
        unlimited.put(atis.State/<DC(2175)>, 
        [EMAIL PROTECTED]) [atis.State]
     DEBUG (DebuggingCacheProxy.put:167) - 
        unlimited.put(atis.State/<WA(2762)>, 
        [EMAIL PROTECTED]) [atis.State]

  *** MySQL query log messages (line breaks and spaces added):
     2 Query    SELECT 
state.state_code,state.state_name,state.country_name,city.city_code
                FROM state LEFT OUTER JOIN city ON 
state.state_code=city.state_code
     2 Query    SELECT city.city_code,city.city_name,city.state_code 
                FROM city 
                WHERE city.city_code='WWAS'

  *** query result #objects=2
     State[code=DC, name=DISTRICT OF COLUMBIA, countryName=USA]
     State[code=WA, name=WASHINGTON, countryName=USA]



<<< selection OQL (UNEXPECTED RESULT !!!) >>>
  *** OQL: SELECT  DISTINCT State FROM atis.State State
         WHERE  (State.name = $1 OR State.cities.name = $2)
      - $1="WASHINGTON"
      - $2="WASHINGTON"

  *** Castor log messages (linebreaks and spaces added):
     DEBUG (PreparedStatementProxy.<init>:77) -
          Creating prepared statement proxy for SQL statement
          SELECT DISTINCT 
state.state_code,state.state_name,state.country_name,city.city_code
          FROM state LEFT OUTER JOIN city ON 
state.state_code=city.state_code,city city_0
          WHERE state.state_code=city_0.state_code
          AND (( state.state_name = ? OR city_0.city_name = ? ))
     DEBUG (DebuggingCacheProxy.remove:176) -
          unlimited.remove(atis.State/<DC(2175)>) [atis.State]
     DEBUG (DebuggingCacheProxy.remove:176) -
          unlimited.remove(atis.City/<WWAS(2677522)>) [atis.City]
     DEBUG (PreparedStatementProxy.<init>:77) -
          Creating prepared statement proxy for SQL statement
          SELECT city.city_code,city.city_name,city.state_code 
          FROM city 
          WHERE city.city_code=?
     DEBUG (ConnectionProxy.invoke:71) - Committing JDBC Connection instance.
     DEBUG (ConnectionProxy.invoke:69) - Closing JDBC Connection instance.
     DEBUG (DebuggingCacheProxy.put:167) -
          unlimited.put(atis.City/<WWAS(2677522)>, [EMAIL PROTECTED])
          [atis.City]
     DEBUG (DebuggingCacheProxy.put:167) - 
          unlimited.put(atis.State/<DC(2175)>, [EMAIL PROTECTED])
          [atis.State]

  *** MySQL query log messages (line breaks and spaces added):
     2 Query   SELECT  DISTINCT 
state.state_code,state.state_name,state.country_name,city.city_code 
               FROM state LEFT OUTER JOIN city ON 
state.state_code=city.state_code,city city_0 
               WHERE state.state_code=city_0.state_code 
               AND (( state.state_name = 'WASHINGTON' OR city_0.city_name = 
'WASHINGTON' ))
     2 Query   SELECT city.city_code,city.city_name,city.state_code 
               FROM city 
               WHERE city.city_code='WWAS'

  *** result #objects=1
      State[code=DC, name=DISTRICT OF COLUMBIA, countryName=USA]

  *** expected result:
        Since the state_name of 'WA' state is 'WASHINGTON'
      and city_name of 'WWAS' city is 'WASHINGTON',
      the result of the avobe OQL contains two State objects:
      'DC' and 'WA'.

  *** study:
        The above SQL generated by Castor does not select State objects
      that have no related City object because LEFT JOIN is spoiled
      by "state.state_code=city_0.state_code" expression in the WHERE clause.
      The SQL and result are not changed if the "depends" attribute
      in the City mapping is removed, i.e. they are related objects.

      Again, the SQL is:
             SELECT DISTINCT 
state.state_code,state.state_name,state.country_name,
             city.city_code 
             FROM state LEFT OUTER JOIN city ON 
state.state_code=city.state_code,city city_0 
             WHERE state.state_code=city_0.state_code 
             AND (( state.state_name = 'WASHINGTON' OR city_0.city_name = 
'WASHINGTON' ))

        On the other hand, the following SQL selects all the expected states
      whether they have at least one city or not.
 
      mysql> SELECT DISTINCT 
state.state_code,state.state_name,state.country_name,
             city.city_code
          -> FROM state LEFT OUTER JOIN city ON state.state_code=city.state_code
          -> WHERE state.state_name = 'WASHINGTON' OR city.city_name = 
'WASHINGTON';
      +------------+----------------------+--------------+-----------+
      | state_code | state_name           | country_name | city_code |
      +------------+----------------------+--------------+-----------+
      | DC         | DISTRICT OF COLUMBIA | USA          | WWAS      |
      | WA         | WASHINGTON           | USA          | NULL      |
      +------------+----------------------+--------------+-----------+
      2 rows in set (0.00 sec)
 

----
Akihito NAKAMURA



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to