I have an application on Google Cloud that has its data stored on Datastore and is being accessed using the JPA API with the help of DataNucleus middleware. Everything works as expected when the runtime is Java8.
DN does not work with Java11. So I now want to rewrite the data access code by replacing the JPA API / DN with either the (1) datastore native API, or, (2) Objectify.
Option 1:
Datastore native API come in two flavors:
(a) com\google\appengine\api\datastore
(b) com\google\cloud\datastore
. With the latter (albeit the older) API, converting from the Entity to the app-specific Java class was as simple as
appObj.set((<coltype>)entObj.getProperty("appObjColName"))
and so on.
But Google recommends to move to com\google\cloud\datastore as mentioned here.With the new API, it is not as straightforward as the older API to convert from Entity type to app-specific type because the retuned Entity type (in the new API) has a completely different structure.Because of the above reasons, I have chosen to adopt the "Objectify" route.
Option 2:
With Objectify v6.1.1, here is the issue that I am facing. I have this app-specific type:
@Entitypublic class Countries implements Serializable { private static final long serialVersionUID = 5260516669119830294L; @Id private String countryIden = null; private String countryName = null; private Long countryVersion = 0L; public Countries() { super(); } public String getCountryName() { return countryName; } public void setCountryName(String countryName) { this.countryName = countryName; } public String getCountryIden() { return countryIden; } public void setCountryIden(String countryIden) { this.countryIden = countryIden; } public Long getCountryVersion() { return countryVersion; } public void setCountryVersion(Long countryVersion) { this.countryVersion = countryVersion; }}
.....and this is how I use Objectify to retrieve all data in this type from the Datastore
public class DaoCountry { private static Logger logger = Logger.getLogger("DaoCountry"); public synchronized List<Countries> getAllCountries () { List<Countries> listOfCountries= null; try (Closeable session = ObjectifyService.begin()) { listOfCountries = ofy().load().type(Countries.class).list(); logger.info("listOfCountries: " + new Gson().toJson(listOfCountries)); } return listOfPatient; }}
On the server side, this is what I get.....
[{"countryIden":"1","countryVersion":0},{"countryIden":"10","countryVersion":0},{"countryIden":"100","countryVersion":0},{"countryIden":"101","countryVersion":0},{"countryIden":"102","countryVersion":0},{"countryIden":"103","countryVersion":0},{"countryIden":"104","countryVersion":0},{"countryIden":"105","countryVersion":0},{"countryIden":"106","countryVersion":0},{"countryIden":"107","countryVersion":0},{"countryIden":"108","countryVersion":0},{"countryIden":"109","countryVersion":0},{"countryIden":"151","countryVersion":0},{"countryIden":"152","countryVersion"…[message truncated due to size]
So as can be seen, the query returns countryIden
and countryVersion
but NOT countryName
.
The following screen-grab shows that the countryName "column" exists in the datastore and also has data in it.
Question: What am I doing wrong here?
Edit:I tried the same logic above, but on a different Kind
. All I got back was the column marked as @Id
, a column whose type was Boolean
and the version
column whose type is long
. There are many columns whose type is String
and those were not returned.So it looks like the query is ignoring those columns whose type is String
.
Any suggestions?
EDIT in response to Jim Morrison's answer:The field names are what they were in the POJO when I was using JPA. Of course, the field names had@Column
annotations as COUNTRY_ID
, COUNTRY_NAME
and COUNTRY_VERSION
.
So should I rename by POJO fields from
private String countryIden = null;private String countryName = null;private Long countryVersion = 0L;
to
private String COUNTRY_IDEN = null;private String COUNTRY_NAME = null;private Long COUNTRY_VERSION = 0L;
I say this because when executing this API...
listOfCountries = ofy().load().type(Countries.class).list();
there is no opportunity to provide column names.