I'm trying to think of how to get around this problem. I have an ORMlite object that can belong to multiple Categories; I'm using another table (i.e. a ForeignCollection) to track many-to-many connections between my objects and categories.
The problem is if I update the object with changed categories, the new categories are added, but old ones are not removed.
In the JavaDoc for the update method of DAO I see this text:
NOTE: Typically this will not save changes made to foreign objects or
to foreign collections.
My question is about the use of the word "typically." Does this mean that there IS a way through some sort of setting to make sure that updates update related foreign objects/collections?
Or should I read the sentence as if "typically" was not there, assume there is no automatic method, and that I need to run extra queries on committing each object to delete old categories?
The problem is if I update the object with changed categories, the new categories are added, but old ones are not removed.
So you have an object that has a foreign collection of categories:
#ForeignCollectionField
ForeignCollection<Category> categories;
If you run categories.add(category1) or categories.remove(category1), then the underlying collection should remove those from its associated table using a built-in DAO.
If you are changing the category list some other way then you are going to have to remove the Category entries by hand using the categoryDao directly.
... about the use of the word "typically." Does this mean that there IS a way through some sort of setting to make sure that updates update related foreign objects/collections?
Not sure why I left the word "typically" there. I think it was a blanket statement to take into account the various auto-create, auto-refresh, etc. field settings -- I'm not sure. In any case, I've removed it from the code base.
ORMLite has no way to know if foreign objects have been changed. It does not create magic proxy objects nor sessions so that it can tell when a foreign object has been updated. You have to be explicit about what you want updated when. The documentation on foreign collections is quite explicit about it.
OrmLite will not save objects to ForeignCollections automatically. You have to store and delete these objects yourself. Ormlite will retrieve the objects in the ForeignCollection automatically for you, provided you set the right parameters in the annotation.
Ormlite is "lite". It does ORM, but not completely. It's not JPA or Hibernate.
I solved this problem by adding the new Category to the table Categories directly, instead of adding a new category to the Object's foreignCollection.
This can be done by simply creating a category ado and adding a new element.
A newCategory.setObject(object) is needed in order to create the relation with the object.
Hope this helps.
Related
I have an app already in production, and now I want to change database property names in several tables to reduce bandwidth.
For eg, realtime database existing property is:
purchasePrice: 60
and by using #PropertyName, I want to change it so it now looks like this:
pp: 60
The changed POJO now has #PropertyName like:
#PropertyName("pp")
public float purchasePrice;
The question is: What is the best migration strategy so that all existing 'purchasePrice' is updated to new name in the realtime database, i.e 'pp' in this example case?
One naive approach I can think of is, on app update at client end, pull all data using old POJOs and assign each property to new POJOs (newPOJO.pp = oldPOJO.purchasePrice) and then save it in DB. But there should be a better way, as I have many POJOs.
Thanks,
If you want to change the name of a field in the database everywhere it occurs, there is really no easy way to do this. You're going to have to:
Query all of the nodes where it could appear
Check to see if the field needs to change
Write the new data back to that location
Whether you do that with code that uses #PropertyName or something more generic, it doesn't really matter.
I need to synchronize the data in my application. I do the request to the server, bind and use copyToRealmOrUpdate(Iterable<E> objects) to add or update this data to the database.
But my files can be invalidated and I need something to delete everything that don't have at the data that return at the request. I don't want to truncate or do a manual delete to do this because performance matters.
IDEA 1
#beeender
What do you think about use the PRIMARY_KEY of the table to delete the data that I don't want (or I don't need)?
Looks like:
1º: If the database was populated, get all primary key and add it in an HashMap (or anything that do the same).
2º: Update the data or add, removes the item of the HashMap (using the primary key) if it was updated or added.
3º: Remove all items of HashMap on the Realm.
Maybe the In memory Realm would be a good choice for you in this situation. You can find related documents here .
By using the in-memory Realm:
The db will be empty when you start a new app process
After you close all the instances of the Realm, the data will be cleared as well.
----------------------------------- Update for deleting data for normal case -----------------------------------------
For deleting, there are some options you can use
Remove all data for a specific model, see doc
realm.allObjects(MyModel.class).clear();
Remove entire data from a given Realm by (Realm API)[https://realm.io/docs/java/latest/api/io/realm/Realm.html#deleteRealm(io.realm.RealmConfiguration)] (close all instances first!):
Realm.deleteRealm(realmConfig);
Or just remove the Realm file through normal java API.
If you really care about the performance, you could consider to separate those data in one Realm, and use option 2 or 3 to remove them. See doc here for using different Realm through RealmConfiguration.
----------------------------------- Update for delete by Date field ------------------------------------------------------
For your user case, this would be a good choice:
Add a Date field to your model, and add annotation #Index to make query faster on it.
Update/add rows and set the modified date to current time.
Delete the objects where its modifiedDate is before the current date.realm.where(MyModel.class).lessThan("modifiedDate", currentDate).findAll().clear()
NOTE: "The dates are truncated with a precision of one second. In order to maintain compatibility between 32 bits and 64 bits devices, it is not possible to store dates before 1900-12-13 and after 2038-01-19." See current limitations. If you could modified the table in a very short time which the accuracy doesn't fit, consider to use a int field instead. You can get the column's max value by RealmResult.max()
I use ActiveAndroid to save my objects to the database, it works mostly well. In my application, I use the following scenario:
I save a new object to a table in my database
I select some objects from that table
I add them to a List<>
I delete everything from that table
I use foreach on my List and call 'save' on each object
And here comes the problem. In my table the objects are saved except the aforementioned most recently saved one. I created a counter to check, how many 'save' was called: the counter is 1 more than the count of the objects in the table. I debugged it, no exception was raised, the save was called. I use the latest version of ActiveAndroid (3.0.99)
Any ideas what I should check?
Well, the problem can be seen in the scenario if your read it through.
I copy an existing object to the memory and try to reinsert it. The ORM checks only the mID of the object and if it is not null, it calls an update. As my object had an id, it was tried to be updated though the table was truncated so nothing was updated.
I don't know if it is intentional that the model never checks the table just its own id but it can lead to issues like this.
I am writing a card-game application.
I represent the Deck of cards using an ArrayList<ImageView>, and i represent the "cards stacking up on the table"(For rollback purposes) in a Stack<ImageView>.
How can I store the state of both the ArrayList<ImageView> and the Stack<ImageView> in order to pick up from where i left off earlier.
I can only think of SharedPreferences, which only supports primitives and Sets.
Your might want to consider using a SQLite database for this. Your columns would be the properties on the object you want to store. If you add on "order" property you can then use the SQL logic
order by `order` DESC
at the end of your query to get them back in the correct order.
Here's a guide:
http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/
I have some Items with a foreign key to a parent Category. Is there an efficient way to query some Items and get fully populated Category objects?
The only approach I'm aware of is to use foreignAutoRefresh, or to refresh the Categories manually after the Item query, but this would result in an extra db hit for EACH Item object.
This can be done with a single JOIN, but if I do that is there any support for automatically building out the Category objects? Part (maybe all) of the problem is I don't fully understand the QueryBuilder's join functionality, but based on this answer it sounds like it doesn't do this:
Notice, however, that you can only get entities from the query builder
using this mechanism. If you want to get your two description fields
from different objects then you would have to still use a raw-query.
Alternatively, is there a way to refresh a collection of Categories in place with a single query, so that I can take the bare id-only Categories from the Item query and refresh them all?
In case it's of interest, the goal is to display these hierarchically in an ExpandableListView. Please let me know if I can provide any more info. I am comfortable throwing some SQL at it and populating Java objects myself if need be, but I'd rather stay within the framework if possible.