[objectify-appengine] Simple Key question

69 views
Skip to first unread message

strawman

unread,
Apr 26, 2010, 7:54:22 PM4/26/10
to objectify-appengine
Folks,

Two Entities.

rfq:

@Id Long rfqID;
String title;
List<Key<RfqLane>> rfqLanes;
@Transient List<RfqLane> rfqLaneList;

rfqlane:

@Id Long rfqLaneID;
String desc;


In the above, when a new rfq entity is created , I need rfqlanes to be
created too... Do, I need to persist each of the rfqlane objects to
get access to their ids? Then I need to create Key objects for these
and associate them in the rfq object?

Am I right here? So, the DAO code should persist the dependent data
first before ...

Or am I completely offbase here. ....What's the cleanest way to build
relationships like the above

Cheers
Strawman


--
Subscription settings: http://groups.google.com/group/objectify-appengine/subscribe?hl=en

Scott Hernandez

unread,
Apr 26, 2010, 8:03:58 PM4/26/10
to objectify...@googlegroups.com
Yes, that is probably correct.

However, if you have objects with relationships there they are
dependent and the "child" is not shared, then you may be better off
inverting the relationship like this:

class Rfq {
@Id Long id;
String title;
@Transient List<RfqLane> rfqLanes; //filled with a query for RfqLane.rfq = this
}

class RfqLane {
@Id Long id;
Key<Rfq> rfq;
String desc;

strawman

unread,
Apr 26, 2010, 9:53:05 PM4/26/10
to objectify-appengine
Thanks, Your second suggestion is what I am implementing. It makes
more sense in my case.
However,in the DAO, when I save rfq object ..all is well. When i save
the rfqlane object in a loop, I get a "id cannot be zero" error.

public Rfq addRfq(Rfq rfq) {
Objectify objectify = ObjectifyService.begin();
objectify.put(rfq);
List<RfqLane> lanes = rfq.getRfqLaneList();
for (RfqLane rfqLane : lanes) {
rfqLane.setRfq(new Key<Rfq>(Rfq.class, new Long(rfq.getRfqID())));
objectify.put(rfqLane);
}
return rfq;
}

I get the error in the "objectify.put(rfqLane)" line... Am I missing
something?

Scott Hernandez

unread,
Apr 26, 2010, 10:03:09 PM4/26/10
to objectify...@googlegroups.com
Can you include your class defs? I suspect you used "long"
(primitive-inits to 0) when you wanted "Long" (boxed, inits to null).

Generally you want to get the the result of your put as the key. It is
less likely to cause errors and is more readable;)

Key<Rfq> rfcKey = objectify.put(rfq);
...
rfqLane.setRfq(rfqKey);

strawman

unread,
Apr 26, 2010, 10:07:40 PM4/26/10
to objectify-appengine
Here they are...I'll try what you suggested.

public class Rfq implements Serializable {
@Id Long rfqID;
String title;
String phone;
Key<Subscriber> subscriber;
@Transient String subscriberID;
@Transient List<RfqLane> rfqLaneList;
@Transient List<RfqService> rfqServiceList;

}

public class RfqLane implements Serializable{

@Id Long rfqLaneID;
Key<Rfq> rfq;
String round;
Key<Lane> lane;
Date shipDate;
@Transient List<RfqCarrier> rfqCarrierList;
@Transient Lane laneObject;

Scott Hernandez

unread,
Apr 26, 2010, 10:18:26 PM4/26/10
to objectify...@googlegroups.com
Also, in general, a stack trace is always preferred. That will let us
know what component the error comes from.

There doesn't appear to be anything wrong but you have left off the
methods so it hard to know.

strawman

unread,
Apr 26, 2010, 10:22:26 PM4/26/10
to objectify-appengine
StackTrace below.. The other methods in the class are just getters/
setters..

java.lang.IllegalArgumentException: id cannot be zero
at
com.google.appengine.api.datastore.KeyFactory.createKey(KeyFactory.java:
44)
at
com.googlecode.objectify.ObjectifyFactory.typedKeyToRawKey(ObjectifyFactory.java:
283)
at
com.googlecode.objectify.impl.save.LeafFieldSaver.prepareForSave(LeafFieldSaver.java:
176)
at
com.googlecode.objectify.impl.save.LeafFieldSaver.saveValue(LeafFieldSaver.java:
68)
at com.googlecode.objectify.impl.save.FieldSaver.save(FieldSaver.java:
139)
at com.googlecode.objectify.impl.save.ClassSaver.save(ClassSaver.java:
110)
at com.googlecode.objectify.impl.Transmog.save(Transmog.java:342)
at
com.googlecode.objectify.impl.EntityMetadata.toEntity(EntityMetadata.java:
228)
at com.googlecode.objectify.impl.ObjectifyImpl.put(ObjectifyImpl.java:
176)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:
100)
at
com.googlecode.objectify.impl.DatastoreTimeoutRetryProxy.invoke(DatastoreTimeoutRetryProxy.java:
59)
at $Proxy29.put(Unknown Source)
at com.steer.contrax.server.rfq.RfqDao.addRfq(RfqDao.java:97)
at
com.steer.contrax.server.rfq.RfqServiceImpl.saveRfq(RfqServiceImpl.java:
51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:
100)
at
com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:
562)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:
188)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:
224)
at
com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:
62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:713)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:
511)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1166)
at
com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:
51)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1157)
at
com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:
43)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1157)
at
com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:
122)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1157)
at
org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:
388)
at
org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:
216)
at
org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:
182)
at
org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:
765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:
418)
at
com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:
70)
at
org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:
152)
at com.google.appengine.tools.development.JettyContainerService
$ApiProxyHandler.handle(JettyContainerService.java:349)
at
org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:
152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:
542)
at org.mortbay.jetty.HttpConnection
$RequestHandler.content(HttpConnection.java:938)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at
org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:
409)
at org.mortbay.thread.QueuedThreadPool
$PoolThread.run(QueuedThreadPool.java:582)

Scott Hernandez

unread,
Apr 26, 2010, 10:31:20 PM4/26/10
to objectify...@googlegroups.com
Yep, one of the keys you are saving on that object has an id value of
0. Was that stack trace from before you used the key returned from put
(for rfq)? If not, then it must be the lane field with a 0 id.

Have you got it figured out now?

strawman

unread,
Apr 26, 2010, 10:43:59 PM4/26/10
to objectify-appengine
Yep. there was a key object with 0 in it...I will rectify that. thanks
for your help
> read more »
Reply all
Reply to author
Forward
0 new messages