Win a copy of Rust Web Development this week in the Other Languages forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • Ron McLeod
  • Liutauras Vilda
  • Jeanne Boyarsky
Sheriffs:
  • Junilu Lacar
  • Rob Spoor
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Tim Moores
  • Jesse Silverman
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Piet Souris
  • Frits Walraven

Should an ID field be included in an Android Room Entity constructor?

 
Ranch Hand
Posts: 73
2
IntelliJ IDE Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
**Problem:** I've been learning Android Room and encountered a problem where a zero number (0) primary key ID exist. When I try to do an `insert` it returns a `UNIQUE` error pertaining to this zero ID existing. I suspect my handling of the constructor might be wrong the use of zero as a "new" insert ID; but it seems logical in a "get" List<> in a DAO, you would want to return the IDs of table entries?

**What I'm trying to do:** My understanding is that you have the option to incldue an ID field in your constructor. However, Android Developer's link about Entities (see below)  example has the ID included. So, I included the the ID field as a parameter so my entity would return an ID. So when I have an insert in my DAO, I pass a '0' which has never caused this issue in 100's of `insert cases ( the db has 8 tables) because all the tables will return the next value. However, now I have encountered this. I'm not sure the solution and what I should do at this point with 8 table Entity constructors with ID. Should I be passing zero to the constructor on new inserts?

https://developer.android.com/reference/androidx/room/Entity - the Android Developers example

**Example:** NoteID is the PK for this Notes.Class (this has getters and setters not included):

 
Saloon Keeper
Posts: 24811
172
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To properly define an ORM (JPA-style) Entity, you should define the following:

1. no-argument constructor

2. equals() method using the primary key and only the primary key

3. hashCode method using the primary key and only the primary key

You need a no-argument constructor because the ORM will be allocating places to catch incoming data from the database and the incoming values would stomp on on your constructed Entity instance.

You need special implementations of equals() and hashCode() because Entities are uniquely defined by their primary keys and ONLY by their primary keys. You can fetch a record with ID=1254 and accountBalance of $14.74, update the balance to $2375, and it's still the same record.
 
Scott Vallery
Ranch Hand
Posts: 73
2
IntelliJ IDE Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Tim,

Thanks for your response and help. I will need to admit, ORM and JPA had no meaning to me and I had to look these up before responding. I can't find these concepts in any Android Room implementation documentation online, instead, with different ORMs with the Hibernate being commonly referenced. Are you suggesting I use something different than Android Room for Android SQLite database interactions?
 
Saloon Keeper
Posts: 7224
169
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Room (which is an ORM) is indeed the way to go. JPA does not exist on Android, and none of the things Tim H lists are necessary with Room.

With Room, you would have a constructor that takes an additional ID, but your code would not use that constructor.

So you would have something like this:



along with the various getters and setters. Your code would only use the latter constructor, and let Room handle the IDs.
 
Tim Holloway
Saloon Keeper
Posts: 24811
172
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ORM = Object Relational Manager. The idea that database tables can be represented as Java classes and that database relationships can be represented by Java object references. It allows database fields to be immediately accessible from Java code without manually pushing and pulling them and reduces the need for the pesky SQL JOIN.

JPA = Java Persistence Architecture. A  standard ORM interface system defined as part of the Enterprise JavaBeans component of Java Enterprise Edition (now Jakarta EE).

Hibernate = An ORM provider. Originally provided a proprietary interface system, but the Hibernate team helped define JPA and now Hibernate JPA is the preferred implementation.

Room = An ORM provider for Android. Most of the major JEE providers are too heavy for many android devices, so Room provides similar services within Android's limitations.

Whether or not the items I mentioned are essential for Room to fully operate properly I cannot confirm. For full JEE, they are definitely essential because on the big systems, you can have multiple instances of the same row and there are caching mechanisms that need to be able to find instances quickly in cache (using the hashCode).

Nevertheless, it doesn't hurt to have them and I do so in my own Room objects. It's good practice and make be useful if you want to be able to use the same entity class definitions on a full JEE implementation.

As for Tim Moores' example, I've not seen that, but chasing Android documentation through all its mutations via the Internet is a nightmare, so I can't say it's not recommended, but here's an extract from one of my own Room Entities:


This is basically standard JPA usage and it works fine for me.
 
Scott Vallery
Ranch Hand
Posts: 73
2
IntelliJ IDE Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Tim M. and Tim H.,

Thanks for taking time to explain and providing an example. I will explore and consider this. My DB is pretty big with 8 tables and 3 Join tables, this would be cumbersome task to update since I need to learn a bit more.

Again, appreciate the advice and assistance!

UPDATE: Adding the add'l constructor suggested by Tim Moore worked! Thanks again.
 
Tim Holloway
Saloon Keeper
Posts: 24811
172
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Scott Vallery wrote:My DB is pretty big with 8 tables and 3 Join tables



Scott Vallery wrote:this would be cumbersome task to update...


Something that may help. I don't know all the nuances of Android Studio, but a lot of the modern IDEs have templates to create "boilerplate" code like constructors, setters, getters, and even entire blank classes. It's a lot more fun if you can just "click a button". Android Studio is an offshoot of IntelliJ IDEA, and even 15 years back when it was the corporate standard for where I worked back then it had those kinds of powers.
 
Scott Vallery
Ranch Hand
Posts: 73
2
IntelliJ IDE Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Tim H.,

Thanks for the pointer on the boilerplate templates. I've been working through Intellij since I initially started with Java. Your suggestion probably would have helped me tremendously - certainly in the future. I'm in so deep now, maybe there is still the possibility of refactoring. I've been working on this app for a year and half off and on, trying to learn everything in the process. So again, this will be very helpful.
reply
    Bookmark Topic Watch Topic
  • New Topic