Can I temporarily suspend auto-generated identifier in ORMLite?

I am using Android with ORMLite in the small application that I am currently writing. The application is designed to create a working import / export function for which I use the Simple XML structure. And everything works perfectly, to a certain extent.

The situation is this: object A contains a foreign key that refers to object B, which refers to object C through the foreign key itself. Database export is great. Import works with a little caution, namely, that it works as long as the identifiers of all objects are sequential and begin with 1. But if the database is fragmented, that is, I deleted the record here and there after exporting the database, I have " holes "in the generated XML structure. Examples of objects can be:

@DatabaseTable("orders") public class Order { @DatabaseField(generatedId = true) private int _id; @DatabaseField(columnName="date") private Date _date; @DatabaseField(columnName="cost") private double _cost; @DatabaseField(foreign = true, columnName="customer_id") private Customer _customer; // ... more fields, getters and setters } @DatabaseTable("customers") public class Customer { @DatabaseField(generatedId = true); private int _id; @DatabaseField private String _name; // ... more fields, getters and setters } 

Let's say I have a database with two clients (id 1 and 2) that contain orders from 1 to 5 and 6 to 8 respectively. Exporting this and then re-importing into a clean database works fine. If, however, I delete customer 1 and their orders and export it, the exporter will write his identifier as they are, i.e.

 <customer id="2">...</customer> 

and

 <order id="6">...</order> <order id="7">...</order> <order id="8">...</order> <order id="9">...</order> 

etc .. When I import data into a new database, I will first save the client object through

 custDao.create((Customer)x); 

and then each of their orders through

 orderDao.create((Order)o); 

The problem is that the create function ignores the provided identifier (which is not 0), and the newly created identifier for the client is 1 (in a new empty database). The same goes for orders. But since they refer to the client with id = 2, the connection between them is broken.

So, after this somewhat long explanation, here is my question: is there any way to tell ORMLite to take the provided value for the generated field and run it instead? I would be fine if any exception is thrown if the create function finds a row already in the table with the same identifier, but continues to save the record otherwise ... I thought about this: all objects should be sorted by identifier using the Comparator interface; sort ArrayList with imported objects; for each object - read the alleged id into int, - save to the database using dao.create, - if the new identifier of the object is different from the expected id, change it to dao.updateId, - go to the next object in the list .. But it seems too cumbersome and error prone: what if the create method tries to generate an identifier that you simply reassigned to the previous object using updateId?

I do not think that my situation is so rare that no one has come across this before. I would appreciate a solution!

Regards, Todor

0
source share
1 answer

ORMLite supports the allowGeneratedIdInsert=true parameter for the @DatabaseField annotation, which allows you to insert an object with an identifier already set in the generated identification table. If the value of the ID field is null or the default (0, ...), then the database will generate an identifier. This is not supported by all types of databases (e.g. Derby). Here is another discussion about this particular topic.


I think that here we need to make a correct schedule of objects by associating the corresponding Customer with their Order objects before saving them to disk. If you are reading your Customers in memory, then read in the Order objects and set the actual Customer object on each of them. When you create each Customer object in the database, ORMLite will change the id field to the generated field, which will change it to the customer_id field stored in each Order .

If you have a ton of data and you cannot read all of this in memory for one (or for some other reason), you can always create a Map<Integer,Integer> and save the Customer identifier from the XML associated with the identifier that you will receive after creating it in the database. Then, when you load Order objects, you can set the new corrected identifier to a foreign object.

Hope this helps. Let me find out more information about how you read objects, and I can give a better example of constructing a graph of objects.

+2
source

Source: https://habr.com/ru/post/895118/


All Articles