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