Hello:

When I try to load a subclass object in my transaction, I get a persistence
exception.
I wrote a simple test case that illustrates it.  It is contrived but it is
doing the same
thing my app is doing.

Here is the exception I get:
org.exolab.castor.jdo.PersistenceException: Requested to load/fetch an
object of type persistent.Administrator, where persistent storage returned
an object of type class persistent.Subscriber
        at
org.exolab.castor.persist.TransactionContext.load(TransactionContext.java:62
2)
        at org.exolab.castor.persist.QueryResults.fetch(QueryResults.java:229)
        at
org.exolab.castor.jdo.engine.OQLQueryImpl$OQLEnumeration.hasMore(OQLQueryImp
l.java:641)
        at
org.exolab.castor.jdo.engine.OQLQueryImpl$OQLEnumeration.hasMore(OQLQueryImp
l.java:624)
        at action.SubclassTest.doGet(SubclassTest.java:30)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at
org.apache.catalina.servlets.InvokerServlet.serveRequest(InvokerServlet.java
:466)
        at
org.apache.catalina.servlets.InvokerServlet.doGet(InvokerServlet.java:180)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Application
FilterChain.java:247)
        at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterCh
ain.java:193)
        at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.ja
va:260)
        at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:643)
        at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
        at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.ja
va:191)
        at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:643)
        at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
        at
org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2415)
        at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180
)
        at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:643)
        at
org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.
java:170)
        at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:641)
        at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172
)
        at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:641)
        at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
        at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java
:174)
        at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:643)
        at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
        at org.apache.catalina.connector.warp.WarpRequestHandler.handle(Unknown
Source)
        at org.apache.catalina.connector.warp.WarpConnection.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:536)

You can see it for yourself here:
        http://dev.jammconsulting.com/castorTest/servlet/action.SubclassTest

I am using Castor 0.9.4.3 on Tomcat 4.1.8 with MySql 3.23.55, Apache 2.0.44
and RedHat Linux 8.0.

Here is my test code:
package action;

import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.exolab.castor.jdo.*;
import persistent.*;
import util.*;

public class SubclassTest extends HttpServlet {
  protected void doGet(HttpServletRequest req, HttpServletResponse res)
  throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter writer = res.getWriter();
    try {
      Database db = DbUtil.getDatabase();
      OQLQuery query = db.getOQLQuery("select s from
"+Subscriber.class.getName()+" s where s.emailAddress = $1" );
      query.bind("[EMAIL PROTECTED]");
      QueryResults results = query.execute();
      if( results.hasMore() ) {
        Subscriber subscriber = (Subscriber) results.next();
        writer.println( "<P>Found subscriber:
"+subscriber.getEmailAddress() );
      }

      query = db.getOQLQuery("select a from
"+Administrator.class.getName()+" a where a.emailAddress = $1 and a.password
= $2" );
      query.bind("[EMAIL PROTECTED]");
      query.bind("test");
      results = query.execute();
      if( results.hasMore() ) {
        Administrator administrator = (Administrator) results.next();
        writer.println( "<P>Found administrator:
"+administrator.getEmailAddress()+" with password:
"+administrator.getPassword() );
      }
      db.commit();
      db.close();

    } catch( Exception e ) {
      writer.println( "Caught exception: "+e );
      writer.println( "<PRE>" );
      e.printStackTrace(writer);
      writer.println( "</PRE>" );
    } finally {
      writer.close();
    }
  }
}

The code that loads the database is here:
package util;

import java.net.*;
import org.exolab.castor.jdo.*;
import org.exolab.castor.mapping.*;

public class DbUtil {
  private static JDO jdo = null;

  public static synchronized Database getDatabase()
  throws Exception {
    if( jdo == null ) {
      jdo = new JDO();
      jdo.setDatabaseName("castorTest");
      ClassLoader loader = DbUtil.class.getClassLoader();
      URL url = loader.getResource("database.xml");
      jdo.loadConfiguration(url.toString());
    }
    Database db = jdo.getDatabase();
    db.begin();
    return db;
  }
}

Here is the Subscriber class:
package persistent;

import java.util.*;

public class Subscriber {
  private int id;
  private String emailAddress;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getEmailAddress() {
    return emailAddress;
  }

  public void setEmailAddress(String emailAddress) {
    this.emailAddress = emailAddress;
  }
}

Here is the Administrator class:
package persistent;

public class Administrator extends Subscriber {
  private String password;

  public int getId() {
    return super.getId();
  }

  public void setId(int id) {
    super.setId(id);
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }
}

Here is my database schema:
DROP TABLE IF EXISTS Administrator;
CREATE TABLE Administrator (
    id                int             PRIMARY KEY,
    password          varchar(255)    NOT NULL,
    INDEX (password)
) TYPE = InnoDB;

DROP TABLE IF EXISTS Subscriber;
CREATE TABLE Subscriber (
    id                int             PRIMARY KEY,
    emailAddress      varchar(255)    NOT NULL,
    INDEX (emailAddress)
) TYPE = InnoDB;

Here is my mapping file:
<?xml version="1.0"?>

<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
                         "http://castor.exolab.org/mapping.dtd";>

<mapping>
  <class name="persistent.Subscriber"
         identity="id"
         access="shared"
         key-generator="MAX"
         auto-complete="false">
    <map-to table="Subscriber" />
    <cache-type type="count-limited" />
    <field name="id"
           type="integer"
           get-method="getId"
           set-method="setId">
      <sql name="id"
           type="integer" />
    </field>
    <field name="emailAddress"
           type="java.lang.String"
           required="true"
           get-method="getEmailAddress"
           set-method="setEmailAddress">
      <sql name="emailAddress"
           type="char" />
    </field>
  </class>

  <class name="persistent.Administrator"
         identity="id"
         access="shared"
         extends="persistent.Subscriber"
         key-generator="MAX"
         auto-complete="false">
    <map-to table="Administrator" />
    <cache-type type="count-limited" />
    <field name="id"
           type="integer"
           get-method="getId"
           set-method="setId">
      <sql name="id"
           type="integer" />
    </field>
    <field name="password"
           type="java.lang.String"
           required="true"
           get-method="getPassword"
           set-method="setPassword">
      <sql name="password"
           type="char" />
    </field>
  </class>
</mapping>

Here is my database file:
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE databases PUBLIC "-//EXOLAB/Castor JDO Configuration DTD Version
1.0//EN" "http://castor.exolab.org/jdo-conf.dtd";>

<database name="castorTest" engine="mysql">
  <driver class-name="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/castorTest">
    <param name="user" value="castorTest" />
    <param name="password" value="abc1122" />
  </driver>
  <mapping href="mapping.xml"/>
</database>

And finally, here is the code I used to initialize the database:
package init;

import org.exolab.castor.jdo.*;
import java.io.*;
import javax.servlet.http.*;
import persistent.*;
import util.*;

public class InitDb extends HttpServlet {
  public void doGet(HttpServletRequest req, HttpServletResponse res)
  throws IOException {
    res.setContentType("text/html");
    PrintWriter writer = res.getWriter();

    try {

      writer.println( "Removing existing administrator objects" );
      writer.println( "<P>" );
      Database db = DbUtil.getDatabase();
      OQLQuery query = db.getOQLQuery("select a from
"+Administrator.class.getName()+" a");
      QueryResults results = query.execute();
      while(results.hasMore()) {
        Administrator administrator = (Administrator) results.next();
        db.remove(administrator);
      }
      db.commit();
      db.close();

      writer.println( "Removing existing subscriber objects" );
      writer.println( "<P>" );
      db = DbUtil.getDatabase();
      query = db.getOQLQuery("select s from "+Subscriber.class.getName()+"
s");
      results = query.execute();
      while(results.hasMore()) {
        Subscriber subscriber = (Subscriber) results.next();
        db.remove(subscriber);
      }
      db.commit();
      db.close();

      writer.println( "Adding test objects" );
      writer.println( "<P>" );

      db = DbUtil.getDatabase();
      Administrator administrator = new Administrator();
      administrator.setEmailAddress("[EMAIL PROTECTED]");
      administrator.setPassword("test");
      db.create(administrator);
      administrator = new Administrator();
      administrator.setEmailAddress("[EMAIL PROTECTED]");
      administrator.setPassword("test1");
      db.create(administrator);
      db.commit();
      db.close();

      db = DbUtil.getDatabase();
      Subscriber subscriber = new Subscriber();
      subscriber.setEmailAddress("[EMAIL PROTECTED]");
      db.create(subscriber);
      db.commit();
      db.close();

      db = DbUtil.getDatabase();
      subscriber = new Subscriber();
      subscriber.setEmailAddress("[EMAIL PROTECTED]");
      db.create(subscriber);
      db.commit();
      db.close();


      db = DbUtil.getDatabase();
      subscriber = new Subscriber();
      subscriber.setEmailAddress("[EMAIL PROTECTED]");
      db.create(subscriber);
      db.commit();
      db.close();

      writer.println( "Done" );
    } catch( Exception e ) {
      writer.println( "Caught Exception: "+ e );
      writer.println( "<PRE>" );
      e.printStackTrace(writer);
      writer.println( "</PRE>" );
    } finally {
      writer.close();
    }
  }
}

Thanks,
        Neil.

--
Neil Aggarwal
JAMM Consulting, Inc.    (972) 612-6056, http://www.JAMMConsulting.com
Custom Internet Development    Websites, Ecommerce, Java, databases

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

Reply via email to