Ormlite - deleting nested objects from ForeignCollection but not from database - android

I have ContactItem which contains ForeignCollection of GroupItem:
public class ContactItem implements Parcelable{
#DatabaseField(generatedId = true)
private Integer id;
#DatabaseField(dataType = DataType.STRING, columnName = Constants.CONTACT_NAME)
private String name;
#DatabaseField(dataType = DataType.STRING, columnName = Constants.CONTACT_NUMBER)
private String number;
#DatabaseField(dataType = DataType.INTEGER, columnName = Constants.CONTACT_ICON)
private int icon;
#DatabaseField(dataType = DataType.INTEGER, columnName = Constants.CONTACT_DAYS)
private int days;
#DatabaseField(foreign=true,canBeNull = true,foreignAutoRefresh = true,columnName = Constants.CONTACT_GROUP)
private GroupItem group;
#ForeignCollectionField(columnName = Constants.CONTACT_GROUP_LIST)
private ForeignCollection<GroupItem> groups;
}
and GroupItem, which contains ForeignCollection of ContactItem:
public class GroupItem implements Parcelable{
#DatabaseField(generatedId = true)
private Integer id;
#DatabaseField(dataType = DataType.STRING, columnName = Constants.GROUP_NAME)
private String name;
#DatabaseField(dataType = DataType.INTEGER, columnName = Constants.GROUP_ICON)
private int icon;
#DatabaseField(dataType = DataType.INTEGER, columnName = Constants.GROUP_COUNT)
private int count;
#DatabaseField(foreign=true,canBeNull = true,foreignAutoRefresh = true, columnName = Constants.GROUP_CONTACT)
private ContactItem contact;
#ForeignCollectionField(eager = true, columnName=Constants.GROUP_CONTACTS_LIST)
private ForeignCollection<ContactItem> contacts;
#DatabaseField(dataType = DataType.INTEGER, columnName = Constants.GROUP_DAYS)
private int days;
}
and i need to delete ContactItem from GroupItem's ForeignCollection of ContactItems. I do it like that:
public void removeContactFromGroup(GroupItem group, ContactItem contact)
{
DatabaseHandler db = new DatabaseHandler(context.getApplicationContext());
Dao<GroupItem,Integer> daoGroup = null;
Dao<ContactItem,Integer> daoContact = null;
GroupItem newGroup = null;
try {
daoGroup = db.getGroupDao();
daoContact = db.getContactDao();
UpdateBuilder<GroupItem, Integer> updateBuilder = daoGroup.updateBuilder();
newGroup = daoGroup.queryForId(group.getId());
if ( newGroup.getContactCollection().contains(contact))
{
}
}
catch(Exception e)
{
Log.i(" saveGroupContacts database problem","It is cause problem");
e.printStackTrace();
}
}
but it delets ContactItem from whole database. But I need to remove it only from ForeignCollection. How can I implement this?

I solved my issue by maybe not elegant, but workable solution : I simply set my nested object in those, which contains it to null and update object-container with dao :
public void removeContactFromGroup(GroupItem group, ContactItem contact)
{
DatabaseHandler db = new DatabaseHandler(context.getApplicationContext());
Dao<GroupItem,Integer> daoGroup = null;
Dao<ContactItem,Integer> daoContact = null;
GroupItem newGroup = null;
ContactItem contactFromDb = null;
try {
daoGroup = db.getGroupDao();
daoContact = db.getContactDao();
UpdateBuilder<GroupItem, Integer> updateBuilder = daoGroup.updateBuilder();
newGroup = daoGroup.queryForId(group.getId());
contactFromDb = daoContact.queryForId(contact.getId());
contactFromDb.setContactGroup(null);
daoContact.update(contactFromDb);
}
catch(Exception e)
{
Log.i(" saveGroupContacts database problem","It is cause problem");
e.printStackTrace();
}
}
Worked for me.

Related

Java Android about Hashmap

I am trying to retrieve from UpdateProduct (Hashmap) to be able to modify my items by clicking the button. I implemented void modifyItem, but I see it is missing something.
File DataBase.java
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NOM = "Produits.db";
private static final String TABLE_PRODUCT = "Produits";
private static final String COLONNE_ID = "_id";
private static final String COLONNE_NAMEPRODUCT = "_nameProduct";
public void UpdateProduct(HashMap<String,String> object, String newValue) {
if(object == null) return;
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLONNE_NAMEPRODUCT, newValue);
int rows = db.update(TABLE_PRODUCT, values, "_id = ?", new String[]{object.get("id")});
db.close();
}
// MainActivity
Here my method to retrieve Hashmap data from UpdateProduct**
public void modifyItem(View view) {
if (objectSelected == null) return;
**????** selectedProduct = objectSelected.get("product");
if (selectedProduct != null && !selectedProduct.isEmpty()) {
DataBase.UpdateProduct(selectedProduct);
}
}`
Tryning to solve my project problems

Select rows comparing two column value in ormlite while using raw query

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();
}

How to delete an object where it consist with multiple objects in ORM-Lite

I am using ORM-lite for an Android application, Model class is as follows,
#DatabaseTable(tableName = "pageimage")
public class PageImage
{
#DatabaseField(generatedId = true)
private int pageimageId;
#DatabaseField(foreign = true, foreignAutoRefresh = true, uniqueCombo=true)
private Page page;
#DatabaseField(foreign = true, foreignAutoRefresh = true, uniqueCombo=true)
private Image image;
#DatabaseField
private int order;
//implementation
}
PageImage object is created with combination of Page and Image objects referenced to Page and Image tables. i have searched a lot but still unable to find a away to delete a PageImage object where Page id = "some value" and Image id = "some value" .
Appreciate any ideas.
You can use DeleteBuilder to do that.
private void deletePageItem(Page page, Image image) {
try {
Dao<PageItem, ?> dao = mOpenHelper.getDao(PageItem.class);
DeleteBuilder<PageItem, ?> deleteBuilder = dao.deleteBuilder();
deleteBuilder.where().eq(PageItem.COLUMN_IMAGE, image).and().eq(PageItem.COLUMN_PAGE, page);
deleteBuilder.delete();
} catch (SQLException e) {
e.printStackTrace();
}
}
where mOpenHelper is entity extended from OrmLiteSqliteOpenHelper
PageItem.java
#DatabaseTable(tableName = "pageimage")
public class PageItem {
public static final String COLUMN_PAGE = "page";
public static final String COLUMN_IMAGE = "image";
#DatabaseField(generatedId = true)
private int pageimageId;
#DatabaseField(columnName = COLUMN_PAGE, foreign = true, foreignAutoRefresh = true, uniqueCombo = true)
private Page page;
#DatabaseField(columnName = COLUMN_IMAGE, foreign = true, foreignAutoRefresh = true, uniqueCombo = true)
private Image image;
#DatabaseField
private int order;
}

Insert row in SQLite with Ormlite containing ENUM_INTEGER and DATE_TIME data type

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.

How to create DataTableConfig for a class with a ForeignCollection?

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

Categories

Resources