Auto increment ID Insert Data ORMLITE - android

I'm new to Android and I have problem with ORMLITE.
For example let's say I have this table:
#DatabaseTable(tableName = "accounts")
public class Account {
#DatabaseField(id = true)
private int id;
#DatabaseField(canBeNull = false)
private String name;
…
and I want to add new data into my table without setting id.
I tried this way:
#DatabaseTable(tableName = "accounts")
public class Account {
#DatabaseField(generatedId = true,allowGeneratedIdInsert=true)
private int id;
#DatabaseField(canBeNull = false)
private String name;
…
> Account acc = new Account();
>
> acc.setName("Example");
>
> AccountDao.createOrupdate(acc);
Here I can't insert acc into my database because acc id is zero. I want to generate id. Can I use autoincrement?

Here i can't insert acc into my database because acc id is zero. I want to generate id. Can i use autoincrement ?
So to quote the javadocs for the allowGeneratedIdInsert field in #DatabaseField:
If this is set to true then inserting an object with the ID field already set will not override it with a generated-id. This is useful when you have a table where items sometimes have IDs and sometimes need them generated. This only works if the database supports this behavior and if generatedId() is also true for the field.
So if you have acc.id set to a non-0 value, it should be inserted into the database with the id from acc. If you want acc to get an auto-generated id then you should just set acc.id to be 0.
For an example, you could take a look at the ORMLite Android test class. Search for the testCreateWithAllowGeneratedIdInsert() method which has code like:
AllowGeneratedIdInsert foo = new AllowGeneratedIdInsert();
assertEquals(1, dao.create(foo));
AllowGeneratedIdInsert result = dao.queryForId(foo.id);
assertEquals(foo.id, result.id);
...
AllowGeneratedIdInsert foo3 = new AllowGeneratedIdInsert();
foo3.id = 10002;
assertEquals(1, dao.create(foo3));
result = dao.queryForId(foo3.id);
assertEquals(foo3.id, result.id);
NOTE: the docs mention that this only works if the database supports it but Sqlite is one of those databases.

Use Wrapper class instead of int
#DatabaseField(id = true)
private Integer id;

Related

How to get specific column using Android Room

I'm trying to get id column from my database, ad it to ArrayList and to each id add "\t0",
My database is created using Room, i have a lot of column which one of them is
#PrimaryKey(autoGenerate = true)
private int id;
I am operating using ItemDAO and i have there function
#Query("SELECT * FROM item")
List<Item> getItems();
Which writes to ArrayList<Items> all of contents
I was thinking of running it trough the loop getting id and adding to ArrayList<String> but this doesn't seems to be eficient.
Your DAO:
#Query("SELECT Id FROM item")
List<Integer> getAllIds();
Your model:
#ColumnInfo(name = "Id")
#PrimaryKey(autoGenerate = true)
private int id;
In you query SELECT * FROM item * means select All, put there your column name and you will get list of objects from that column
Example: Select all items in id column SELECT id FROM item
I tried to modify and test #Valgaal 's solution. It turns out that Room can also return other type of values, more than just id (or integer).
For example, you can write an item class like this:
#Entity(tableName = Item.TABLE_NAME)
public class Item {
public static final String TABLE_NAME = "ItemsTable";
public static final String COL_DESC = "Description";
#PrimaryKey(autoGenerate = true)
private int id;
#ColumnInfo(name = COL_DESC)
private String description;
// getter & setter...
}
And then, you can write Dao like this:
#Dao
public interface ItemDao {
#Query("SELECT * FROM " + Item.TABLE_NAME)
List<Item> getItems();
#Query("SELECT " + Item.COL_DESC + " FROM " + Item.TABLE_NAME)
List<String> getItemDescriptions();
}
And it's functional as it should be.
I guess all of the other data types that Room can save (including custom types?) can be queried (and returned lists of specific column data) by the same logic above. Hope this would help someone in the future!
For returning multiple columns, create a pojo class that can be set as a return type for your DAO function
Note the select query should contain the Pojo class variable name (can be done via AS keyword)
Detailed answer here
https://stackoverflow.com/a/50802209/1029110
I landed on this question for my issue...but didnt find answer. So this may help others.

How to use a different foreign key in ORMLite?

I have a problem with a foreign key in ORMLite I have 2 classes QuestionDb and ResponsesDb which are the following :
public class ResponsesDb {
public static final String FIELD_ID = "id";
#DatabaseField(generatedId = true,columnName=FIELD_ID)
private int id;
#DatabaseField(canBeNull = false, foreign = true, foreignColumnName=QuestionDb.FIELD_REF)
private QuestionDb question;
#DatabaseField(canBeNull = false)
private String answer;
}
And :
#DatabaseTable(tableName = "question")
public class QuestionDb implements Serializable {
public static final String FIELD_REF = "ref";
private static final long serialVersionUID = 4106020204304605623L;
#DatabaseField(generatedId = true)
private int id;
#DatabaseField(canBeNull = false, unique = true, columnName=FIELD_REF, index=true)
private String ref;
#ForeignCollectionField(foreignFieldName = "question", eager = true)
private ForeignCollection<ResponsesDb> responses;
}
My problem is when i do that :
QueryBuilder<QuestionDb, Integer> questionQuery = helper
.getQuestionDao().queryBuilder();
QueryBuilder<ResponsesDb, Integer> responseQuery = helper
.getResponseDao().queryBuilder();
responseQuery = responseQuery.join(questionQuery);
I recieve that :
05-27 12:00:01.577: W/System.err(7272): java.sql.SQLException: Could not find a foreign class model.ormlite.tableClass.ResponsesDb field in class model.ormlite.tableClass.QuestionDb or vice versa
But if I remove the field foreignColumnName=QuestionDb.FIELD_REF from question field's annotation in ResponsesDb, the query works.
The fact is that as my program update the database, the id field can change so I want that the foreign key is ref. Do you have any idea how I can fix this problem ?
You can use a string as a foreign key. What you cannot do is define a foreign key with a foreignColumnName that is not the key of the other object.
From the example in the ORMLite documentation:
With foreign objects, just the id field from the Account is persisted
to the Order table as the column "account_id".
In this case, you have in QuestionDb:
#DatabaseField(generatedId = true)
private int id;
The generatedId annotation means that this is the id of the table. Having marked ref as unique will create a unique index, but it does not make it a candidate key. Thus it cannot be used as a foreign key from another table.
In short: if you need a string foreign key, then you can. Just define a string primary key in the referenced table. (i.e. remove the id field and put #DatabaseField(id = true) in the ref field.
Going further back, howerver, I don't understand why you claim:
The fact is that as my program update the database, the id field can
change
The generatedId value will not change for a row after inserting it. It's perfect for use as a foreign key! :)

Android OrmLite emptyString for String defaultValue

I am using OrmLite 4.46 to manage my database for my android application.
And i have one problem:
I have the following code for my model:
public class Item extends Model {
#DatabaseField(generatedId = true)
private long id;
#DatabaseField(columnName = "item_name", defaultValue = "")
private String name;
#DatabaseField(columnName = "item_count", defaultValue = "0")
private int count;
public Item() {
super();
}
}
And the problem is here :
#DatabaseField(columnName = "item_name", defaultValue = "")
private String name;
When i am creating a new Item() with no arguments and i save it in the database, normally in the column item_name it should save an empty String.
But when i am retrieving the item from the database and i try
String itemName = item.getName().trim() I get a NullPointerException
So it seems that the name is null.
Also i checked the created table from the above model in the sqlite db file and when i set defaultValue="" the column is created with no default value.
Does anybody know of any solution to this problem?
You can initialize name field to empty string at class level like:
#DatabaseField(columnName = "item_name", defaultValue = "")
private String name = "";
This will initialize name field to empty string when you create object of class Item and save it to database.
When you retrieve it from database the name field will be empty ("") instead of null.
When i am creating a new Item() with no arguments and i save it in the database, normally in the column item_name it should save an empty String.
Although #Rakesh's answer is correct, this turns out to be a bug in ORMLite. The code is supposed to insert the defaultValue during a create if the field is null. However, there was an errant .equals("") that was stopping this.
I've submitted the following bug report and have fixed it in trunk. It will be in 4.47.

ORMlite not returning the object I just saved

Here is my code that fails ( it is running within an activity and the DB helper creates the WishList object fine in the database )
DatabaseHelper helper = DatabaseHelper.getInstance( getActivity() );
int savedID = 0;
WishList wl = new WishList();
wl.setName("abc");
try {
savedID = helper.getWishListDao().create(wl);
WishList wl_saved = helper.getWishListDao().queryForId( savedID );
wl_saved.getId();
} catch (SQLException e) {
e.printStackTrace();
}
Here is my entity. The ID field is auto generated.
#DatabaseTable
public class WishList {
#DatabaseField(generatedId = true)
private int id;
#DatabaseField( canBeNull = false , unique = true )
private String name;
#ForeignCollectionField
private ForeignCollection<WishItem> items;
...
What is wrong is the ID that is generated in the Database is not the same one that that ORMlite returns in the call below. It returns 1.
savedID = helper.getWishListDao().create(wl);
The ID in the database is actually 37. Any ideas what I may be doing wrong?
Using version 4.41
ORMLite's Dao.create(...) method does not return the ID of the newly created object but the number of rows in the database that were changed – usually 1. Here are the javadocs for Dao.create(...).
Create a new row in the database from an object. If the object being created uses DatabaseField.generatedId() then the data parameter will be modified and set with the corresponding id from the database. ...
Returns: The number of rows updated in the database. This should be 1.
When ORMLite creates the object, the generated ID is then set to the id field afterwards. To find the ID of your new object you get it from the object itself:
// create returns 1 row changed
helper.getWishListDao().create(wl);
// the id field is set on the w1 object after it was created
savedID = w1.getId();

ORMLite foreign field null on create, not null on query

When writing an instance of my data class to the database via ORMLite, and one of the child members (a foreign field) is null, I get back a non null child member.
Data classes as follows:
public class Site {
// snip
#DatabaseField(foreign = true, canBeNull = true)
private InstallationType installationType;
}
public class InstallationType {
#DatabaseField(generatedId = true)
private int id;
#DatabaseField
private String name;
}
When I read my instance of the Site class again via
getSiteDao().queryForId(id);
the installationType member is non null, but with a non-existent id. The only way the rest of our application can now work with this object, is if I manually do a lookup through the InstallationTypeDAO and set what I get back on the site. Query will sometimes return null as per the documentation.
Is there a way of getting ORMLite to set this member to null?
This was a bug in ORMLite that was fixed in version 4.15 (3/7/2011). Here's the change log file. What version are you using? Have you tried to update? Here's the bug report page:
Currently the following test passes so I think we have good coverage on that bug.
#Test
public void testForeignNull() throws Exception {
Dao<Foreign, Integer> dao = createDao(Foreign.class, true);
Foreign foreign = new Foreign();
foreign.foo = null;
assertEquals(1, dao.create(foreign));
Foreign foreign2 = dao.queryForId(foreign.id);
assertNotNull(foreign2);
assertNull(foreign2.foo);
}
With Foreign having the following fields:
#DatabaseField(generatedId = true)
public int id;
#DatabaseField(foreign = true)
public Foo foo;
If you are up to date in versions, please let me know if you can change the test to get it to fail.

Categories

Resources