Reading a persistent object's variable prevents it from being added to an object later
I am trying to make a new object Session and persist it to the database. It has a persistent variable of object User. I query the DB for the user I want to add to the session. If the user's password doesn't match "hello" (for now obviously), stop. If it does, make a new session, set the regular variables and add sOwner (just set Session's User variable). Like this, the code works but doesn't check the password...
try {
Query u = pm.newQuery(User.class); //Query for user
u.setFilter("email == eaddr");
u.declareImports("import java.lang.String");
u.declareParameters("String eaddr");
@SuppressWarnings("unchecked")
List<User> res = (List<User>)u.execute(email);
sOwner = res.get(0);
//if (!sOwner.getPassword().equals("hello")) { // comment out
//throw new Exception("password not correct"); // these three lines
//} // and it works
sNew = new Session();
sNew.setUser(sOwner);
sNew.setIpAddr(ipAddr);
sNew.setStartedOn(new Date());
sNew.setToken(token);
pm.makePersistent(sNew);
} catch (Exception e) {
}
but without the if statement commented out, the final committing of the changes has this error:
2385571 [btpool0-0] DEBUG DataNucleus.Persistence - Object "com.yachtcloser.server.om.Session@14446bce" (id="com.yachtcloser.server.om.Session:381") is having the value in field "startedOn" replaced by a SCO wrapper
2385571 [btpool0-0] DEBUG DataNucleus.Datastore.Native - INSERT INTO `SESSION` (`TOKEN`,`STARTEDON`,`USERAGENT`,`IPADDR`,`USER_ID_OID`,`ID`) VALUES (<'90a9d90f325c3b'>,<2011-02-24 19:12:15.595>,<null>,<'127.0.0.5'>,<21>,<381>)
2385572 [btpool0-0] DEBUG DataNucleus.Datastore.Persist - Execution Time = 1 ms (number of rows = 1)
2385572 [btpool0-0] DEBUG DataNucleus.Persistence - Insert of object "com.yachtcloser.server.om.Session@14446bce" is calling insertPostProcessing for field "com.yachtcloser.server.om.Session.user"
2385572 [btpool0-0] DEBUG DataNucleus.Persistence - Insert of object "com.yachtcloser.server.om.Session@14446bce" is calling insertPostProcessing for field "com.yachtcloser.server.om.Session.transaction"
2385572 [btpool0-0] DEBUG DataNucleus.Datastore.Retrieve - Closing PreparedStatement org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@2ac7bf18
2385572 [btpool0-0] DEBUG DataNucleus.Persistence - Insert of object "com.yachtcloser.server.om.Session@14446bce" is calling postInsert for field "com.yachtcloser.server.om.Session.user"
2385572 [btpool0-0] DEBUG DataNucleus.Persistence - Insert of object "com.yachtcloser.server.om.Session@14446bce" is calling postInsert for field "com.yachtcloser.server.om.Session.transaction"
2385584 [btpool0-0] DEBUG DataNucleus.Persistence - Object "com.yachtcloser.server.om.Session@14446bce" field "transaction" is replaced by a SCO wrapper of type "org.datanucleus.store.types.sco.backed.List" [cache-values=true, lazy-loading=true, queued-operations=false, allow-nulls=true]
2385585 [btpool0-0] DEBUG com.yachtcloser.server.DispatchServlet - Response Sent:{"cmds":[{"response":"Session 381 created by user 0"}]}
2385585 [btpool0-0] DEBUG DataNucleus.Persistence - ObjectManager internalFlush() process started - 1 dirty objects
2385585 [btpool0-0] DEBUG DataNucleus.Persistence - ObjectManager internalFlush() process finished
2385589 [btpool0-0] ERROR DataNucleus.Persistence - java.lang.NullPointerException
2385590 [btpool0-0] DEBUG DataNucleus.Persistence - Disconnecting com.yachtcloser.server.om.Session@14446bce from StateManager[pc=com.yachtcloser.server.om.Session@14446bce, lifecycle=P_NEW]
Here's the stack trace of the NPE I think:
NestedThrowablesStackTrace:
java.lang.NullPointerException
at org.datanucleus.store.rdbms.sql.SQLStatementHelper.selectMemberOfSourceInStatement(SQLStatementHelper.java:723)
at org.datanucleus.store.rdbms.request.FetchRequest.processMembersOfClass(FetchRequest.java:478)
at org.datanucleus.store.rdbms.request.FetchRequest.<init>(FetchRequest.java:166)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.getFetchRequest(RDBMSPersistenceHandler.java:329)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.fetchObject(RDBMSPersistenceHandler.java:306)
at org.datanucleus.jdo.state.JDOStateManagerImpl.loadFieldsFromDatastore(JDOStateManagerImpl.java:2028)
at org.datanucleus.jdo.state.JDOStateManagerImpl.loadUnloadedFields(JDOStateManagerImpl.java:1685)
at org.datanucleus.jdo.state.JDOStateManagerImpl.runReachability(JDOStateManagerImpl.java:3295)
at org.datanucleus.ObjectManagerImpl.performReachabilityAtCommit(ObjectManagerImpl.java:3415)
at org.datanucleus.ObjectManagerImpl.preCommit(ObjectManagerImpl.java:3268)
at org.datanucleus.ObjectManagerImpl$2.transactionPreCommit(ObjectManagerImpl.java:324)
at org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:394)
at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:279)
at org.datanucleus.jdo.JDOTransaction.commit(JDOTransaction.java:90)
at com.yachtcloser.server.UserContext.finishRequest(UserContext.java:181)
at com.yachtcloser.server.DispatchServlet.doPost(DispatchServlet.java:185)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at com.yachtcloser.server.DispatchServlet.service(DispatchServlet.java:55)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
I tried detaching a copy, and comparing that password, then adding the original query result to the session, that didn't work either. Here's the important part of Session which I can't edit by the way:
@PersistenceCapable(identityType=IdentityType.APPLICATION)
public class Session implements Comparable<Session> {
@PrimaryKey
@Persistent(valueStrategy=IdGeneratorStrategy.INCREMENT)
private long id;
@Persistent
private User user;
datanucleus-core-2.2.2.jar, datanucleus-connectionpool-2.0.3.jar, datanucleus-googlecollections-2.2.0-release.jar, datanucleus-jdo-query-2.2.1.jar, datanucleus-rdbms-2开发者_如何学Python.2.2.jar, jdo2-api-2.3-ec.jar, datanucleus-enhancer-2.1.3.jar, asm-3.3.1.jar those are the jar files I see
A query generates SQL. That is printed in the DataNucleus log. Consequently you ought to check the SQL generated for your query. The stack trace is created from tx.commit() yet you don't mention such a call.
You don't say the version of DataNucleus in use ... of each plugin jar.
精彩评论