I can't seem to get my projection query to return anything but null, not sure what I'm doing wrong.
Here's the code where I set up and call the query:
Query query1 = OfyService.ofy().load().type(CargoEntity.class).
project("imageUrl", "latitude", "longitude").distinct(false); //filter("group", group);
// Execute the query:
List<Entity> results = query1.list();
logger.warning("(Query from datastore results.isEmpty()) : " + (results.isEmpty()));
logger.warning("(Group = ) : " + group);
if (!results.isEmpty()) {
logger.warning("(Query from datastore results.size()) : " + (results.size()));
//Create STRTree-Index.
STRtree strTree = new STRtree();
GeometryFactory gf = new GeometryFactory();
//Loop through the result list from DataStore.
for (Entity result : results) {
STRLeaf leaf = new STRLeaf((float)result.getProperty("latitude"), (float)result.getProperty("longitude"), (String)result.getProperty("imageUrl"));
Coordinate coord = new Coordinate(leaf.getLongitude(), leaf.getLatitude());
Point point = gf.createPoint(coord);
//Add result to index.
strTree.insert(point.getEnvelopeInternal(), leaf);
}
I'm really new to this so it could be something obvious that i'm missing. I do see the indexes in the developers console though. Here's what the properties in my Entity looks like:
#Entity
#Index
#Cache
public class CargoEntity {
//datastore key
#Id
private String imageUrl;
private float latitude;
private float longitude;
private String group;
#Unindex
private int rating;
#Unindex
private Blob image;
#Unindex
private String email;
#Unindex
private String userName;
#Unindex
private String description;
#Unindex
private Date date;
#Unindex
private String blobKey;
#Unindex
private String type;
#Unindex
private boolean flag;
#Unindex
private int photoOrientation;
public CargoEntity() {
}
//getters and setters below
So apparently I was adding the Entity id to the projection query which is not allowed (or it is allowed but returns null). This post answered the problem.
Google App Engine projection query returns 0 results
Related
I have a parent entity Collection:
#Entity(tableName = "collections")
public class Collection implements Serializable {
#PrimaryKey
#NonNull
public String id;
public String collTitle;
public int isFavorite;
public int wordCount;
Collection(String collTitle, int isFavorite, int wordCount) {
this(UUID.randomUUID().toString(), collTitle, isFavorite, wordCount);
}
#Ignore
Collection(#NonNull String id, String collTitle, int isFavorite, int wordCount) {
this.id = id;
this.collTitle = collTitle;
this.isFavorite = isFavorite;
this.wordCount = wordCount;
}
}
and a child entity Word:
#Entity(tableName = "words",
foreignKeys = #ForeignKey(
entity = Collection.class,
parentColumns = "id",
childColumns = "collId",
onDelete = SET_DEFAULT),
indices = #Index("collId"))
public class Word implements Serializable {
#PrimaryKey
#NonNull
public final String id;
public String wordTitle;
public String collId;
public String pageNum;
public int isFavorite;
public String wordNotes;
#Ignore
Word(String wordTitle, String collId, String pageNum, int isFavorite, String wordNotes) {
this(UUID.randomUUID().toString(), wordTitle, collId, pageNum, isFavorite, wordNotes);
}
Word(#NonNull String id, String wordTitle, String collId, String pageNum, int isFavorite,
String wordNotes) {
this.id = id;
this.wordTitle = wordTitle;
this.collId = collId;
this.pageNum = pageNum;
this.isFavorite = isFavorite;
this.wordNotes = wordNotes;
}
}
At the time of inserting a new Collection, I give wordCount as 0 because every new collection would have 0 words associated with it. However, when inserting a new Word, I have to choose one collection from the defined collections and use its 'id' as 'collId' (Foreign Key).
Now I need to retrieve a list of Collection objects with 'wordCount' field containing the actual number of words associated with each Collection object. As already mentioned, 'wordCount' field is assigned a value of 0 at the time of insertion of a Collection object.
I just hope I made my question clear. Kindly suggest a query that serves my purpose. And I don't want to have the result in the form of a new POJO class like, for example, CollectionsAndWords.
Any help would be a great help!
OK, i solved it in the following way:
In my Collection entity, I annotated the wordCount as follows:
#ColumnInfo(name = "word_count")
public int wordCount;
and made changes to the constructors by removing this field:
Collection(String collTitle, int isFavorite) {
this(UUID.randomUUID().toString(), collTitle, isFavorite);
}
#Ignore
Collection(#NonNull String id, String collTitle, int isFavorite) {
this.id = id;
this.collTitle = collTitle;
this.isFavorite = isFavorite;
}
Finally, I added the following query method in my DAO:
#Query("SELECT collections.id, collections.collTitle, collections.isFavorite, " +
"COUNT(words.collId) as word_count " +
"FROM collections " +
"LEFT JOIN words " +
"ON collections.id = words.collId " +
"GROUP BY collections.id " +
"ORDER BY collections.collTitle")
List<Collection> findAllCollsWithCount();
The LEFT JOIN used in the right manner did all the trick for me.
Note that in above query, I'm not retrieving the wordCount field, I'm just letting a new field to be calculated and mapping it to wordCount. If I retrieve wordCount along with other columns from collections table, I get 02 columns that go by the name of word_count; one with 0 value and other with calculated value (COUNT()). I also tried to annotate wordCount with #Ignore but then Room couldn't find any column to map word_count to.
However, for now, the above solution is perfectly serving my purpose, so it is the answer. It might help someone with the same question.
Thanks!
I have the following database table
#DatabaseTable(tableName = "Order_Details")
public class DB_OrderDetails {
#DatabaseField(generatedId = true)
private int id;
#DatabaseField()
private int order_id_from_order_table;
#DatabaseField()
private String medicine_code;
#DatabaseField()
private String medicine_name;
#DatabaseField()
private String medicine_type;
#DatabaseField()
private int number_of_units_ordered;
#DatabaseField()
private String generic_name;
#DatabaseField()
private String manufacturer_name;
#DatabaseField()
private double ordering_cost;
... }
I am using ormlite for my local db operations. i want to get the result for
SELECT * FROM Order_Details WHERE (medicine_code='xxxx' AND manufacturer_name='yyyy')
and want to get the result returned in
List<DB_OrderDetails>
can anybody suggest me a way to do it?
Use an object of the Where class to build your query.
List<DB_OrderDetails> list;
try {
Dao<DB_OrderDetails, String> dbOrderDetailsStringDao = dbHelper.getOrderDetailsDao();
QueryBuilder<DB_OrderDetails, String> queryBuilder = dbOrderDetailsStringDao.queryBuilder();
Where where = queryBuilder.where();
where.eq("medicine_code", "xxxx");
where.and();
where.eq("manufacturer_name", "yyyy");
PreparedQuery<DB_OrderDetails> preparedQuery = queryBuilder.prepare();
list = dbOrderDetailsStringDao.query(preparedQuery);
} catch (SQLException e) {
e.printStackTrace();
}
I want to update multiple cell of single row with active android.
some thing like this,
new Update(Question.class).set("UserAnswer ="+answerID,
"UserAnswerType = "+userAnswerType)
.where("QID = ?", questionID).execute();
but that will gives me error. is there any other way to do this? or am i missing something?
Here is my Question.class for reference
#Table(name = "Questions")
public class Question extends Model {
#Expose
#Column(name = "QID")
private Integer ID;
#Expose
#Column(name = "AnswerID")
private Integer AnswerID;
#Expose
#Column(name = "UserAnswer")
private Integer UserAnswer;
#Expose
#Column(name = "UserAnswerType")
private Integer UserAnswerType;
//Getter and setter methods for fields
public Question() {
// You have to call super in each constructor to create the table.
super();
}
}
You can do something like below. I have done it in one of my project and it worked fine.
String updateSet = " UserAnswer = ? ," +
" UserAnswerType = ? ";
new Update(Question.class)
.set(updateSet, answerID, userAnswerType)
.where(" QID = ? ", questionID)
.execute();
Following similar pattern for any number of columns will work. In case if you have Boolean type fields in your table, this issue can help you.
We Can achieve it like this way.
StringBuilder data=new StringBuilder();
if (!TextUtils.isEmpty(name.getText().toString()))
{
data.append("Name = '"+name.getText().toString()+"',");
}
if (!TextUtils.isEmpty(age.getText().toString()))
{
data.append("Age = '"+age.getText().toString()+"',");
}
if (!TextUtils.isEmpty(empCode.getText().toString()))
{
data.append("EmployeeCode = '"+empCode.getText().toString()+"',");
}
if (!TextUtils.isEmpty(mobNum.getText().toString()))
{
data.append("MobileNumber = '"+mobNum.getText().toString()+"',");
}
if (!TextUtils.isEmpty(adress.getText().toString()))
{
data.append("address = '"+adress.getText().toString()+"'");
}
String str=data.toString();
//-------------and update query like this-----------------
new Update(EmpProfile.class).set(str).where("EmployeeCode = ?", empCode)
.execute();
String x="sent = 1,file = "+n.getString("file");
new Update(Messages.class)
.set(x)
.where("id = ?", lid)
.execute();
This is my entity class. I use three ENUM_INTEGER data type in this class
#DatabaseTable
public class MessageData {
#DatabaseField(generatedId = true, columnName = ID_FIELD_NAME)
private Integer messageId;
#DatabaseField(dataType = DataType.DATE_TIME, columnName = DATE_FIELD_NAME)
private Date date;
#DatabaseField(dataType = DataType.ENUM_INTEGER, columnName = DIRECTION_FIELD_NAME)
private MessageEnums.MessageDirection direction;
#DatabaseField(columnName = CONTACT_ID_FIELD_NAME)
private String contactId;
#DatabaseField(columnName = MESSAGE_FIELD_NAME)
private String message;
#DatabaseField(dataType = DataType.ENUM_INTEGER, columnName = TYPE_FIELD_NAME)
private MessageEnums.MessageType type;
#DatabaseField(columnName = CONTENT_ADDRESS_FIELD_NAME)
private String contentAddress;
#DatabaseField(dataType = DataType.ENUM_INTEGER, columnName = STATUS_FIELD_NAME)
private MessageEnums.MessageStatus status;
#DatabaseField(columnName = READ_FIELD_NAME)
private boolean read;
//.....
}
and this is my enumeration class
public class MessageEnums {
public enum MessageDirection{
IN,
OUT
}
public enum MessageType{
TEXT,
VOICE,
IMAGE,
STICKER,
AUDIO,
VIDEO,
LOCATION
}
public enum MessageStatus{
PENDING,
SENT,
DELIVERED,
RECEIVED
}
}
I use this code to insert a row
newMessageData = new MessageData(date, MessageEnums.MessageDirection.OUT, params[2], params[1]
, MessageEnums.MessageType.TEXT, "", MessageEnums.MessageStatus.SENT, true);
Dao<MessageData, Integer> dao = myApplication.getMessageDatabaseHelper().getMessageDao();
dao.create(newMessageData);
I get this error after running last line
Unable to run insert stmt on object com.x.xx.database.MessageData#41a72790: INSERT INTO messagedata (date ,direction ,contactID ,message ,type ,contentAddress ,status ,read ) VALUES (?,?,?,?,?,?,?,?)
hope somebody help me!
The problem is from date field. when I changed data type from DATE_TIME to DATE_STRING problem solved. I don't know what is the problem of DATE_TIME.
I have two legacy classes that I want to persist via ormlite 4.48.
Those classes can't be modified, so I can't use the nice annotations.
Fortunately, DatabaseTableConfig came to the rescue.
Here my classes:
public class RedditLink extends RedditType {
// Thing
private String id;
private String name;
private String kind;
private String data;
// Votable
private int ups;
private int downs;
// Uncomment if this ever matters private boolean likes;
// Created
private long created_utc;
// Link
private String author;
private String domain;
private int num_comments;
private boolean over18;
private boolean is_self;
private String permalink;
private String subreddit;
private String subredditId;
private String title;
private String url;
private String selftext;
private String thumbnail;
private RedditLinkList list;
... Getters and setters
}
and
public class RedditLinkList {
private int id;
public static final RedditLinkList EMPTY = new RedditLinkList();
public Collection<RedditLink> links = new ArrayList<RedditLink>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Collection<RedditLink> getLinks() {
return links;
}
public void setLinks(Collection<RedditLink> links) {
this.links = links;
}
}
I get the following error
java.lang.IllegalArgumentException: No fields have a DatabaseField annotation in class rainstudios.kelo.data.model.RedditLinkList
at com.j256.ormlite.table.DatabaseTableConfig.extractFieldTypes(DatabaseTableConfig.java:215)
at com.j256.ormlite.table.DatabaseTableConfig.fromClass(DatabaseTableConfig.java:146)
at com.j256.ormlite.table.TableInfo.<init>(TableInfo.java:53)
at com.j256.ormlite.dao.BaseDaoImpl.initialize(BaseDaoImpl.java:151)
at com.j256.ormlite.dao.BaseDaoImpl.<init>(BaseDaoImpl.java:128)
at com.j256.ormlite.dao.BaseDaoImpl.<init>(BaseDaoImpl.java:107)
at com.j256.ormlite.dao.BaseDaoImpl$4.<init>(BaseDaoImpl.java:907)
at com.j256.ormlite.dao.BaseDaoImpl.createDao(BaseDaoImpl.java:907)
at com.j256.ormlite.dao.DaoManager.createDao(DaoManager.java:70)
at com.j256.ormlite.field.FieldType.configDaoInformation(FieldType.java:297)
at com.j256.ormlite.dao.BaseDaoImpl.initialize(BaseDaoImpl.java:201)
at com.j256.ormlite.dao.BaseDaoImpl.<init>(BaseDaoImpl.java:128)
at com.j256.ormlite.dao.BaseDaoImpl.<init>(BaseDaoImpl.java:119)
at com.j256.ormlite.dao.BaseDaoImpl$5.<init>(BaseDaoImpl.java:921)
at com.j256.ormlite.dao.BaseDaoImpl.createDao(BaseDaoImpl.java:921)
at com.j256.ormlite.dao.DaoManager.doCreateDao(DaoManager.java:359)
at com.j256.ormlite.dao.DaoManager.createDao(DaoManager.java:129)
at com.j256.ormlite.table.TableUtils.createTable(TableUtils.java:229)
at com.j256.ormlite.table.TableUtils.createTableIfNotExists(TableUtils.java:84)
at com.octo.android.robospice.persistence.ormlite.InDatabaseObjectPersisterFactory.createTableIfNotExists(InDatabaseObjectPersisterFactory.java:106)
at com.octo.android.robospice.persistence.ormlite.InDatabaseObjectPersisterFactory.initializeTablesIfNeeded(InDatabaseObjectPersisterFactory.java:120)
at com.octo.android.robospice.persistence.ormlite.InDatabaseObjectPersisterFactory.createObjectPersister(InDatabaseObjectPersisterFactory.java:69)
at com.octo.android.robospice.persistence.CacheManager.getObjectPersister(CacheManager.java:183)
at com.octo.android.robospice.persistence.CacheManager.loadDataFromCache(CacheManager.java:68)
at com.octo.android.robospice.request.DefaultRequestRunner.loadDataFromCache(DefaultRequestRunner.java:239)
at com.octo.android.robospice.request.DefaultRequestRunner.processRequest(DefaultRequestRunner.java:88)
at com.octo.android.robospice.request.DefaultRequestRunner$1.run(DefaultRequestRunner.java:201)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Here is the code I use to generate my DatabaseFieldConfig :
//
// Link
//
List<DatabaseFieldConfig> fieldConfigs = new ArrayList<DatabaseFieldConfig>();
DatabaseFieldConfig field1 = new DatabaseFieldConfig("id");
field1.setId(true);
fieldConfigs.add(field1);
DatabaseFieldConfig field2 = new DatabaseFieldConfig("name");
field2.setCanBeNull(false);
fieldConfigs.add(field2);
DatabaseFieldConfig field3 = new DatabaseFieldConfig("url");
fieldConfigs.add(field3);
DatabaseFieldConfig field4 = new DatabaseFieldConfig("title");
fieldConfigs.add(field4);
DatabaseFieldConfig field6 = new DatabaseFieldConfig("author");
fieldConfigs.add(field6);
DatabaseFieldConfig field5 = new DatabaseFieldConfig("subreddit");
fieldConfigs.add(field5);
// #DatabaseField(foreign = true, foreignAutoRefresh = true,
// canBeNull =
// true, columnName = "list_id")
DatabaseFieldConfig field7 = new DatabaseFieldConfig("list");
field7.setForeign(true);
field7.setForeignAutoRefresh(true);
field7.setCanBeNull(true);
field7.setColumnName("list_id");
fieldConfigs.add(field7);
DatabaseTableConfig<RedditLink> link = new DatabaseTableConfig<RedditLink>(
RedditLink.class, fieldConfigs);
//
// List
//
List<DatabaseFieldConfig> fieldListConfigs = new ArrayList<DatabaseFieldConfig>();
DatabaseFieldConfig fieldList1;
fieldList1 = new DatabaseFieldConfig("id");
fieldList1.setColumnName("list_id");
fieldList1.setGeneratedId(true);
fieldListConfigs.add(fieldList1);
DatabaseFieldConfig fieldList2 = new DatabaseFieldConfig("links");
fieldList2.setForeignCollection(true);
fieldList2.setForeignCollectionEager(false);
fieldListConfigs.add(fieldList2);
DatabaseTableConfig<RedditLinkList> list = new DatabaseTableConfig<RedditLinkList>(
RedditLinkList.class, fieldListConfigs);
// Cross references
field7.setForeignTableConfig(list);
fieldList2.setForeignTableConfig(link);
What am I doing wrong?
Note: my app uses ormlite_config.txt cache