Unable to get ID of newly-created JDO persistent entity using GAE/J DataNucleus plug-in version 2.1.2

谁都会走 提交于 2019-12-04 10:30:01

The GAE JDO plugin only ever sets a "gae.pk-id"/"gae.pk-name" field when it reads in a field marked with that from the datastore (just do a search in SVN trunk, FetchFieldManager is the only place where it's loaded - it doesn't set it when it does a PUT). No idea what it did in 1.x, but all of GAE's own tests pass in 2.x as they did in 1.x. But then that "feature" isn't standard JDO anyway, so of little interest to me.

JDO provides lifecycle listener and you could easily enough set up a postStore callback and set some field in your object in that (and not be reliant on AppEngine-specific "features").

Inspired by @DataNucleus's comments, I have made a work-around in a vaguely similar spirit. The work-around set out below works for me, but I find that my underlying issue remains.

All persistent entities that use a (read-only) numeric ID of an encoded key string will need to have their getID() method changing to use the work-around.

Java code

I amend my ID getter method (given earlier) to as follows:

public Long getID()
{
  Long loResult = DataExchange.getIDFromEKSIfIDIsNull(loID, sEncodedKey);
  return loResult;
}

My DataExchange class has the new method:

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

/**
 * Get the ID supplied, or get it from the encoded key string if the ID is
 * <code>null</code>.
 * <br/>
 * This method is necessary since JDO version 3.0.1 introduces a long delay
 * between entity first persistence and ID availability using the DataNucleus
 * GAE primary key ID plug-in.
 * @param loID
 *   The persistent entity ID.
 *   This may be <code>null</code> if the entity has been persisted for the
 *   first time but its generation is delayed (a big hello to JDO version
 *   3.0.1).
 * @param sEncodedKey
 *   The persistent entity encoded key string.
 *   This should be not <code>null</code> if the entity has been persisted.
 * @return
 *   <ul>
 *     <li>
 *       If the persistent entity ID supplied is not <code>null</code>
 *       then return it
 *     </li>
 *     <li>
 *       else if the encoded key string is not <code>null</code> then extract
 *       the ID and return it
 *     </li>
 *     <li>
 *       else return <code>null</code>.
 *     </li>
 *   </ul>
 */
public static Long getIDFromEKSIfIDIsNull(Long loID, String sEncodedKey)
{
  Long loResult = null;

  if (loID != null)
    loResult = loID;
  else if (sEncodedKey != null)
  {
    Key key = KeyFactory.stringToKey(sEncodedKey);
    if (key != null)
    {
      long loIDFromEKS = key.getId();
      loResult = Long.valueOf(loIDFromEKS);
    }
  }

  return loResult;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!