Realm: Order of records was changed - java

I'm trying to develop my Android app with Realm database.
Today I got below problem:
I added a list of records to table and then try to deleted one of them.
after deleting the order of the rest was changed (it's different with the order before deleting).
please see the images below to see detail.
Before deleting
After delete the 3rd item
And the question is: That's is an function or an bug? And how Can I keep the order of record?
I know that I can easy to get the correct order as I want with add a new field as createTime or something like that but I want to find an very simple solution as config something for Realm.

Items in a Realm are not sorted by default, so you should think of any query result as an unordered set unless you explicitly sorted it.
Generally the items will come out in the order you inserted them in, but it is not a guarantee. The underlying reason technical reason is that we compact the data on the disk, so if you delete items in the middle of a list, the last item will be moved to its place.
So the answer is: It is working as intended, and you should use a sorting method if you want your results to be sorted.

Related

What is the correct way to dynamically change columns and data model in nattable?

When changing the number of columns and rows of natTable
After clearing the column list of DataProvider, create a new column item and change the column item list of columnPropertyAccessor.
Then, put the new data model into the filter list and refresh it.
When the 7-column nattable is sorted (ascending or descending) and clicked, it is changed to a different data model (4 columns) as above, but if it is sorted, "CurrentModificationException" and "IndezxOutOfBoundException" occur.
If you exchange data models without sorting, there is no problem.
I don't know which part is causing it.
Is my way of replacing the filter list wrong when changing the data model?
If anyone has encountered a similar error and has solved it, please help.
Well you don't show how you are doing things, so I can't tell any details. But to answer your question, yes I think you are doing things wrong.
In short, if you have a state applied according to a column like sorting or filtering and you change the underlying data structure, things will break as the states does match the structure anymore. Not sure why you think this should work automatically.
If you change the underlying data structure you need to clear structure based states in advance.
There is an example in the NatTable examples application that shows how to change the data provider dynamically. Not sure if the example covers the clearing of states or if this is handled automatically when you are doing things correctly.

How to make a mutual exclusive code section for database access?

Suppose that we want to insert a record in some table. But in order to be allowed to do that, that table must not contain any record with duplicated values in some fields in such a way that database primary keys are not enough for doing that control and it must be done by the application's code. If the code for inserting a record looked like this...
check duplicates
if no duplicates:
insert the record
else:
show the user a error
That code would be wrong because two different threads could make the check of duplicates at the same time, then pass the check, then insert the same record, producing a situation where there are duplications so that the table state is now inconsistent.
As the code is a web application made in Java, I guess that it would be enough to synchronize the critical section with the same static object so that any user that makes the execution flow to get into the critical section must wait for another one that has previously got into that section. But, is that enough? Is there a more elegant way for doing that?
You can use database triggers for that. The correct one to use in this case is "Before Insert" trigger. If the use case is simpler, another option would be to use checks and constraints.
Third option would be to do it in the java code and synchronizing the section like you described would work too.
According to the clarification from the question comments, a unique index is exactly what's needed here. Create a unique index with the name column as well as the boolean column in it. It will then not allow two entries where both columns have the same values.

what to use for this requirement, Array, List, Map,?

While making my program i have come across this requirement that i have to assign unique id's to some Objects that i create. Now i am creating the objects dynamically on GUI, and initially i used simple counter to assign int value to the created node, and it worked just fine.
However the problem that this approach creates is that if while creating the GUI, if some node has to be deleted, this id is also removed and is never used again. With the next new node, everytime i have to use the latest counter value and this creates lot of missing int values if nodes are deleted during the process.
I wanted to reuse those missing id's upon creating of new nodes, for this i am confused which approach i should addopt.
MY Ideas:
Using a ArrayList that contains the available values, plus if a node
is deleted, it's id is added to this list, i sort this list and use
the minimum value for new node. Fine but, when i use this value, if
i remove it from List, the index is not deleted and this causes
problem.
HashMap, similarly like above i add available id's and remove not used, but not sure how to sort this hashMap???
Can you suggest how i should go about it? May be i need some kind of stack where i can push values, sort it and use the minimum value, and if that i used, it is removed from this stack, please give some ideas about this how to accomplish this task???
Keep a list of the deleted IDs, and when you create a new node, check that list for an ID to re-use (doesn't matter which you take); if the list is empty (as it will be initially), get a new ID "the old way". Even more clever: make the list an object that will generate a new ID if there aren't any deleted ones in it, so the caller doesn't have to worry about HOW the ID was arrived at.
You could use a TreeSet (which automatically sorts all entries added from least to greatest) to store the deleted id's (myTreeSet.add(old_id)). That way, when you go to create a new instance, you would check to see if there are any entries in the TreeSet first. To grab the lowest value, you would use myTreeSet.first() (which should be an O(1) operation). If the TreeSet is empty, which means all known id's are currently in use, then you would go ahead and use the next available id as normal.
How about a TreeSet to store the used IDs? You could then use higher(0) to find the lowest free ID. If it returns null, then you know that you have no used IDs.
The first solution works fine only if you have few nodes! Imagine an application with thousands nodes! What about memory consumption?
The Hashmap solution is better to you aims and need less controls.

ScrollMode.FORWARD_ONLY

Even I've searched on google I want to be very sure about a thing.
Does ScrollMode.FORWARD_ONLY means that I will receive the results in the order they are in DB?
I have something like:
Scroller<Integer> foundRecs = new Scroller<Integer>(query.scroll(ScrollMode.FORWARD_ONLY));
Maybe is a stupid question...
That specific API is Hibernate, which I don't know too much about, but I guess it maps down to TYPE_FORWARD_ONLY in the end (and its documentation agrees by mentioning that constant).
If that's the case, then no: this will not influence the order in which items are returned.
It only means that you can only traverse the result once and can only navigate forward (not backwards).
Databases don't really have an "order" in which they store data, because their tables are sets (not lists). If you need some order for your results, then you need to add an ORDER BY to your SQL (or the equivalent in whichever query system you use).
You cannot rely on the physical order of data in the database. This might work if you query only a single table, but will fail as soon as you are using joins.
If you want your data to appear in a specific order, you need an ORDER BY clause.

add to list without bringing whole list into memory

I have a web service that holds information for users. Each user has a list of items, possibly thousands. I want to add an item to the list without loading the entire list. Is there a list implementation that allows you to add elements to the list without bringing the entire list into memory?
A Doubly Linked List. By definition it's not necessary to traverse the list to add something to the end since it contains a pointer to the end.
the list is on a remote database. –
Lumpy
So the list is in a database, so it's not really a Java List? It's just a bunch of database rows? In that case why not just do an insert into the database to add another row?
INSERT INTO list VALUES 1, 2, 3;
Lazy proxies. You can use a JDK dynamic proxy (java.lang.reflect.Proxy) where you store only the information needed for retrieving the items from the database, not the items themselves. Only when calling the get(..), size(), contains(..) methods - fetch the data.
However I have a feeling that you are doing things the wrong way. Give more details about your implementation.
None that I know.
With middlewares such as Terracotta, some collections (such as maps) can be loaded on-demand and partially, but this doesn't exist as-is in the standart JDK.

Categories

Resources