Bruce,

        Thanks for the reply, here is my mapping descriptor...

==================
MAPPING DESCRIPTOR
==================
<?xml version="1.0"?>
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Object Mapping DTD Version 1.0//EN"
                         "http://castor.exolab.org/mapping.dtd";>
<mapping>

  <!-- Role Table Mapping. -->
  <class name="com.searchdog.sysadmin.application.Role" identity="id">
    <map-to table="role" />
    <field name="id">
      <sql name="id" type="integer" />
    </field>
    <field name="name" type="string" required="true">
      <sql name="name" type="varchar" />
    </field>
  </class>

  <!-- User ID Sequence Mapping. -->
  <key-generator name="SEQUENCE" alias="UserID">
    <param name="sequence" value="user_id_seq"/> 
  </key-generator>

  <!-- User Table Mapping. -->
  <class name="com.searchdog.sysadmin.application.User" identity="id" 
key-generator="UserID">
    <map-to table="user" />
    <field name="id">
      <sql name="id" type="integer" />
    </field>
    <field name="firstName" type="string" required="true">
      <sql name="firstname" type="varchar" />
    </field>
    <field name="lastName" type="string" required="true">
      <sql name="lastname" type="varchar" />
    </field>
    <field name="email" type="string" required="true">
      <sql name="email" type="varchar" />
    </field>
    <field name="password" type="string" required="true">
      <sql name="password" type="varchar" />
    </field>

    <!-- User Table References Role Table. -->
    <field name="role" type="com.searchdog.sysadmin.application.Role">
      <sql name="role" />
    </field>
    
    <!-- User Table References Company Table. Many-To-Many. -->
    <field name="companies" type="com.searchdog.sysadmin.application.Company" 
required="false" collection="vector">
      <sql name="companyid" many-table="user_company_rel" many-key="userid"/>
    </field>
  </class>

  <!-- Company ID Sequence Mapping. -->
  <key-generator name="SEQUENCE" alias="CompanyID">
    <param name="sequence" value="company_id_seq"/> 
  </key-generator>

  <!-- Company Table Mapping. -->
  <class name="com.searchdog.sysadmin.application.Company" identity="id" 
key-generator="CompanyID">
    <map-to table="company" />
    <field name="id">
      <sql name="id" type="integer" />
    </field>
    <field name="name" type="string" required="true">
      <sql name="name" type="varchar" />
    </field>
    <field name="address" type="string" required="true">
      <sql name="address" type="varchar" />
    </field>
    <field name="city" type="string" required="true">
      <sql name="city" type="varchar" />
    </field>
    <field name="state" type="string" required="true">
      <sql name="state" type="varchar" />
    </field>
    <field name="zipcode" type="integer" required="true">
      <sql name="zipcode" type="integer" />
    </field>
    <field name="phone" type="string" required="true">
      <sql name="phone" type="varchar" />
    </field>
    <field name="fax" type="string" required="true">
      <sql name="fax" type="varchar" />
    </field>

    <!-- Company Table References User Table. Many-To-Many. -->
    <field name="users" type="com.searchdog.sysadmin.application.User" required="true" 
collection="vector">
      <sql name="userid" many-table="user_company_rel" many-key="companyid"/>
    </field>
  </class>

  <!-- Project ID Sequence Mapping. -->
  <key-generator name="SEQUENCE" alias="ProjectID">
    <param name="sequence" value="project_id_seq"/> 
  </key-generator>

  <!-- Project Table Mapping. -->
  <class name="com.searchdog.pbuilder.application.Project" identity="id" 
key-generator="ProjectID">
    <map-to table="project" />
    <field name="id">
      <sql name="id" type="integer" />
    </field>
    <field name="jobNumber" type="string" required="true">
      <sql name="jobnumber" type="varchar" />
    </field>
    <field name="description" type="string" required="true">
      <sql name="description" type="varchar" />
    </field>
    <field name="phase" type="integer" required="true">
      <sql name="phase" type="integer" />
    </field>
    <field name="status" type="integer" required="true">
      <sql name="status" type="integer" />
    </field>

     <!-- Project Table References Company Table. -->
    <field name="company" type="com.searchdog.sysadmin.application.Company">
      <sql name="company" />
    </field>

    <!-- Project Table References User Table. Many-To-Many. -->
    <field name="users" type="com.searchdog.sysadmin.application.User" required="true" 
collection="vector">
      <sql name="userid" many-table="project_user_rel" many-key="projectid"/>
    </field>
  </class>

</mapping>

Craig Anderson
Netstat Resources, LLC.

-----Original Message-----
From: Bruce Snyder [mailto:[EMAIL PROTECTED]]
Sent: Monday, September 23, 2002 12:06 PM
To: [EMAIL PROTECTED]
Subject: Re: [castor-dev] Problem Updating Objects


This one time, at band camp, Craig M. Anderson said:

...
CMA>    I can add a user just fine, I can also modify and delete the user with no 
problem, except for this single problem. When a user comes into the user manager they 
are presented with a form that lists the users, the query to get this list is done 
setting the database to readonly mode. The user then clicks on the edit button for a 
specific user and is taken to a form contains all the user information, part of this 
form is a set of four radio buttons representing the users role. I can change anything 
about this user but the role with no problem. If I change the role I get the error:
CMA>
CMA>    "Object, com.searchdog.sysadmin.application.User@239780, links to another 
object, com.searchdog.sysadmin.application.Role@af7a03 that is not 
loaded/updated/created in this transaction."
CMA>
CMA>
CMA>    So, to fix this I add the line calling Database.update() on the role object. I 
can now save the updated user, unless I don't change the Role, then I get the error:
CMA>
CMA>    "org.exolab.castor.jdo.DuplicateIdentityException: update object which is 
already in the transaction"
CMA>
CMA>
CMA>    What is going on? I have included my code below so you can view it if 
neccessary, I am using the built in database pooling by Resin and the postgres 
database.
...
CMA>  /**
CMA>   * UpdateUser method updates the submitted User object in the
CMA>   * database using our OR software.
CMA>   */
CMA>  public void updateUser(User updatedUser) throws Exception {
CMA>    // Get a database connection.
CMA>    db = jdo.getDatabase();
CMA>
CMA>    // Update the company in the database.
CMA>    try {
CMA>      // Get the user from the database.
CMA>      db.begin();
CMA>      oql = db.getOQLQuery( "SELECT u FROM com.searchdog.sysadmin.application.User 
u WHERE id = $1" );
CMA>      oql.bind( updatedUser.getId() );
CMA>      result = oql.execute();
CMA>      while (result.hasMore()) {
CMA>        this.user = (User)result.next();
CMA>      }
CMA>      result.close();
CMA>
CMA>      // Update the general user settings.
CMA>      this.user.setFirstName( updatedUser.getFirstName() );
CMA>      this.user.setLastName( updatedUser.getLastName() );
CMA>      this.user.setEmail( updatedUser.getEmail() );
CMA>      this.user.setPassword( updatedUser.getPassword() );
CMA>
CMA>      // Udate the role information.
CMA>      Role updatedRole = updatedUser.getRole();
CMA>      db.update(updatedRole); 
CMA>      this.user.setRole( updatedRole );
CMA>
CMA>      // Save the updated user to the database.
CMA>      oql.close();
CMA>      db.commit();
CMA>      db.close();
CMA>    } catch (Exception e) {
CMA>      // Rollback transaction on failure, throw exception.
CMA>                    if (db.isActive()) {
CMA>                            db.rollback();
CMA>                    }
CMA>      throw new Exception("Error updating User object in the database.", e);
CMA>    }
CMA>  }

It seems that your use of the db.update() method is correct. The getRole()
method performs a query to fetch the Role object and the updateUser()
method performs its own query and update()s the Role object - pretty
straightforward.

I see you're fetching the updatedRole object from the updatedUser
object. But based on the exception that is thrown, it seems that Castor's
cache is not aware of the the Role object being queried in the current
transaction context. I'm assuming that the User object has a one-to-one
relationship with the Role object, but without seeing the mapping I can
only guess. Can you post the mapping descriptor? 

Bruce
--
perl -e 'print unpack("u30","<0G)U8V4\@4VYY9&5R\"F9E<G)E=\$\!F<FEI+F-O;0\`\`");'

----------------------------------------------------------- 
If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
        unsubscribe castor-dev

----------------------------------------------------------- 
If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
        unsubscribe castor-dev

Reply via email to