Sugar ORM in Android: update a saved object in SQLite - android

I'm new to app development using SQLite and Sugar ORM on Android, and have tried to read through the Sugar ORM documentation, but didn't find anything for how to update a saved object in SQLite. Can I still save the object after changing its properties? something like:
Customer myCustomer = (Customer.find(Customer.class, "id = ?", id)).get(0);
myCustomer.setName("new name");
myCustomer.setAddress("new Address");
myCustomer.save(); // is this okay for updating the object?
the save() method won't create another new object while leaving the old entry untouched, right?

Your code should update the row without issue.
From the docs - Update Entity:
Book book = Book.findById(Book.class, 1);
book.title = "updated title here"; // modify the values
book.edition = "3rd edition";
book.save(); // updates the previous entry with new values.

It will update your entity. The Sugar ORM overwriting your existing e.g Name and updated it with "new name" after the save() method call.

Updating a saved object is pretty straightforward.
Retrieve the object;
Object object= Object.findById(Object.class, ID);
Set the attributes you need to;
object.setAttr("new value");
Then finally call save;
object.save();
Alternatively, as someone mentioned above one can choose to use update() which works slightly differently and would ideally be used when changing several attributes;
First create the object and set the necessary attributes;
Object object= new Object();
object.setAttr("some data");
Then set an ID for the Object that ideally already exists in the database in order to target that item for replacement;
object.setID(ID);
And finally;
object.update();

Save and Object methods are completely different and both are really useful.
If you have an object and you say:
Object.save();
That will override all of the other fields as well for example:
column1 column2
1 1
if in your object you have only set column1 corresponding field a number like 2 you will get:
Object.save();
column1 column2
2 NULL
Object.update();
column1 column2
2 1
You don't need to use .setId() explicitly to get update working it looks for a unique item if it's found it will update that,if not it will create a new row.By default an auto increment ID column is added to each of your tables and used as unique ids for update.If you need your own fields to be unique use:
#Unique
String MyID
or for multiple of the same thing you can use:
#MultiUnique("MyFirstID,MySecondID")
public class MyClass extends SugarRecord {...
which both are name of your fields in the table.

Related

Android SQLITE: insertWithOnConflict() duplicates insertion

I want to insert list of objects into my SQLite db. If I do query for each object to check if its present, it takes alot of time for long list (20-30sec).
I used function 'insertWithOnConflict()' to do that faster.
I thought that it will try to insert a row and if record with same value of column entered to function already exists, it will just replace its values (like update) otherwise it will insert new row.
But I checked my DB and it is creating duplicated objects. Any solution for this?
Important information 'COLUMN_OBJECT_ID' is not 'PRIMARY_KEY'. 'PRIMARY_KEY' is autoincrement. But 'COLUMN_OBJECT_ID' has to be unique in this case. So I want to update row with same 'COLUMN_OBJECT_ID' because data inside can change.
Code:
fun saveObjectsToCache(objects: List<Item>) {
val db = getDb()
db.transaction {
objects.forEach {item->
val cv = ContentValues()
cv.apply {
put(COLUMN_OBJECT_ID, item.id)
put(COLUMN_OBJECT_DATA, item.js.toString())
}
insertWithOnConflict(TABLE_OBJECT_CACHE, COLUMN_OBJECT_ID, cv, SQLiteDatabase.CONFLICT_REPLACE)
}
}
}
Looks like you forgot to add a unique constraint on COLUMN_OBJECT_ID.
Because of this, there is no conflict when you add a row with the same COLUMN_OBJECT_ID.
Make COLUMN_OBJECT_ID unique and it should work.
Additionally, if COLUMN_OBJECT_ID is unique, and is what you use for checking existing values in the table, you should probably make it the primary key, instead of the auto increment one you are using right now as the primary key.
It will be more efficient both in memory usage, and in performance

Room database onConflict = OnConflictStrategy.REPLACE not working

I am working on Room database and trying to insert list of items(eg. list of Quotes which contains author name and a quote in my case).
Following is the code I am using:
// view model
BaseApp.daoInstance?.appDao()?.insertQuotes(response!!)
// dao
#Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertQuotes(listData: MutableList<Quote>)
When I try to insert the same data again, it always inserts as a new data instead of replacing with the current items.
I have researched a lot for this OnConflictStrategy.REPLACE but could not find any proper answer.
Is there anyone facing the same issue and found solution or am I doing anything wrong?
Thank you in advance...!!!
Room, will not check and compare if you have the quote already in the DB.
What it will do is look if the primary key already exists in the DB if it does, Room will replace all old data with the new one.
In your case, you are not specifying an ID so the DB is generating a unique one for you.
What you should do is create a Query that will search for this quote in the DB something like this:
#Query("SELECT * from quote_table WHERE author = :author AND quote = :quote")
List<Quote> getQuoteByAuthorAndQuote(string author, string quote);
This should return a list with a single quote if one is found and empty if it does not exist.
If you would like to override the old one just update the data in the Quote POJO and insert it to the DB using Room.
Have you tried to index your main column and mark it as unique?
#Index(value = {"quote"}, unique = true)}
It suppose to search for your unique or primary key and compare then replace, while in your case you're not defining an ID so it will generate a unique one for you, so it won't even compare and will consider any item as a new one.
Write a new query and function to solve this issue.
When I had same problem, changes in imports did the trick, added following import:
import androidx.room.*;

Remove a SQLite string value from my table

I have a column in my SQLite table named 'img_name'. An example of data in that column: '/storage/extSdCard/img1.jpg /storage/extSdCard/img2.jpg /storage/extSdCard/pic3.jpg'. Lets say I wanted to delete an image. I would delete the corresponding word(path). Only problem is, I do not know how to delete a specific word(path) from that column.
Any help will be appreciated.
The way to "delete a specific word" is to update the existing value.
So you will need an UPDATE statement which selects the appropriate rows, and changes the value of the column. The new value will have to be "computed" from the old value, as you would do in a programming language, using string functions.
UPDATE column1
SET column1 = trim(replace(column1||' ','/storage/extSdCard/img2.jpg ',''))
WHERE column2 = 'example'
Note that this is an example only. The correct string manipulation required may be different. Your question does not specify your exact requirements.
Please consult the SQLite documentation and internet articles for details of string functions in SQLite.
Note that this would not be necessary if you didn't store more than one value in a column in each row.
You should get id of your string that you need to remove, and then pass it in to this:
public void deleteById(int id)
{
SQLiteDatabase db=getWritableDatabase();
String[] position =new String[]{id+""};
db.delete("img_name", "id=?", position );
}
Note: "id=?". Replace "id" in this statement by your id column

How to create and insert a new Object into my Database without an ID?

There was some confusion in our team about the creation of a new database object.
The greendao orm generator creates a standard constructor that takes an id as the first value, if an idproperty was created. For most of our databases we don't want to create the id on our own and simply let the database create the id.
At the moment most of the team members pass -1L as an id. This seems to work.
I couldn't find a documented way to create a new object without an id.
What is the correct way to create such an object and in wich cases is a new id generated during the insertion in the database?
just a quick look at the docs for Greendao reveals:
Now have a look at the addNote method, how you insert a new note in
the database:
Note note = new Note(null, noteText, comment, new Date());
noteDao.insert(note);
Log.d("DaoExample", "Inserted new note, ID: " + note.getId());
Just create a Java object and call insert on the DAO. When the insert
method returns, the database id of the just inserted note is already
assigned to the object, as you can see in the log statment.
looks like null is the answer you want.

Insert a relation

I have a relation: an order contains many order-items. I'd like to insert it a single statement rather than: inserting order, obtaining generated order id, setting order-id for every order-item and finally inserting order-items.
For instance:
Order newOrder = new Order();
o.setItems(orderItems);
o.insert();
instead of:
Order newOrder = new Order();
newOrder.insert();
foreach orderItems : orderItem.setOrderId(newOrder.getId());
orderItems.insert();
Thanks.
greenDAO does not support this.
Updating lists of related entities is not trivial because items could be added, updated, or deleted. greenDAO is not Hibernate, so you need to do those things manually.

Categories

Resources