Note: We focus on Android on this page. You can use ObjectBox in a plain Java project as well.
ObjectBox is available from the Central repository. To add ObjectBox to your Android project, open the root build.gradle
file of your project (not the ones for your app or module) and add a global variable for the version and the ObjectBox Gradle plugin:
buildscript {ext.objectboxVersion = '2.9.1'repositories {mavenCentral()// Note: 2.9.0 and older are available on jcenter()}dependencies {// Android Gradle Plugin 3.2.1 or later supported.classpath 'com.android.tools.build:gradle:4.1.0'classpath "io.objectbox:objectbox-gradle-plugin:$objectboxVersion"}}
Open the build.gradle
file for your app or module and, after the com.android.application
plugin, apply the io.objectbox plugin
:
apply plugin: 'com.android.application'apply plugin: 'io.objectbox' // Apply last.
apply plugin: 'com.android.application'apply plugin: 'kotlin-android'apply plugin: 'kotlin-kapt' // Required for annotation processing.apply plugin: 'io.objectbox' // Apply last.
If you encounter any problems in this or later steps, check out the FAQ and Troubleshooting pages.
Then do "Sync Project with Gradle Files" so the Gradle plugin automatically adds the required ObjectBox libraries and code generation tasks.
The ObjectBox plugin uses reasonable defaults and detects most configurations automatically. However, if needed you can configure the model file path, the MyObjectBox package, enable debug mode and more using advanced setup options.
Next, define your model by annotating at least one class with @Entity
and @Id
. A simple entity representing a user could look like this:
// User.java@Entitypublic class User {@Id public long id;public String name;}
// User.kt@Entitydata class User(@Id var id: Long = 0,var name: String? = null)
When using a data class, add default values for all parameters. This will ensure your data class will have a constructor that can be called by ObjectBox. (Technically this is only required if adding properties to the class body, like custom or transient properties or relations, but it's a good idea to do it always.)
Entities must have one @Id
property of type long
(or Long
in Kotlin). If you need to use other types, like a String ID, see the @Id annotation docs. Also, it must have not-private visibility (or a not-private getter and setter method).
Entities also must have a no-args constructor, or for better performance a constructor with all properties as arguments. In the above example, a default, no-args constructor is generated by the compiler.
For a deeper explanation and a look at all other available annotations (e.g. for relations and indexes) check the Entity Annotations page.
Now build your project to generate required classes, for example using Build > Make Project in Android Studio.
Note: If you make significant changes to your entities, e.g. by moving them or modifying annotations, make sure to rebuild the project so generated ObjectBox code is updated.
Among other files ObjectBox generates a JSON model file, by default to app/objectbox-models/default.json
. This JSON file will change every time you change your entities or we make some internal changes to ObjectBox.
Keep this JSON file, commit the changes to version control!
In Android Studio you might have to switch the Project view from Android to Project to see the default.json
model file.
This file keeps track of unique IDs assigned to your entities and properties. This ensures that an older version of your database can be smoothly upgraded if your entities or properties change. It also enables to keep data when renaming entities or properties or to resolve conflicts when two of your developers make changes at the same time.
The following core classes are the essential interface to ObjectBox:
MyObjectBox: Generated based on your entity classes, MyObjectBox supplies a builder to set up a BoxStore for your app.
​BoxStore: The entry point for using ObjectBox. BoxStore is your direct interface to the database and manages Boxes.
​Box: A box persists and queries for entities. For each entity, there is a Box (supplied by BoxStore).
The BoxStore for your app is initialized using the builder returned by the generated MyObjectBox class, for example in a small helper class like this:
public class ObjectBox {private static BoxStore boxStore;​public static void init(Context context) {boxStore = MyObjectBox.builder().androidContext(context.getApplicationContext()).build();}​public static BoxStore get() { return boxStore; }}
object ObjectBox {lateinit var boxStore: BoxStoreprivate set​fun init(context: Context) {boxStore = MyObjectBox.builder().androidContext(context.applicationContext).build()}}
You might receive crash reports due to UnsatisfiedLinkError
or LinkageError
on the build call. See App Bundle, split APKs and Multidex for solutions.
The best time to initialize ObjectBox is when your app starts. We suggest to do it in the onCreate
method of your Application class:
public class ExampleApp extends Application {@Overridepublic void onCreate() {super.onCreate();ObjectBox.init(this);}}
class ExampleApp : Application() {override fun onCreate() {super.onCreate()ObjectBox.init(this)}}
Now you can easily get a hold of BoxStore throughout your app (usually in fragments, activities) and access the specific Box that you need:
Box<User> userBox = ObjectBox.get().boxFor(User.class);
val userBox: Box<User> = ObjectBox.boxStore.boxFor()
Here, User
is an ObjectBox entity. And now that we have its Box, we can start storing and retrieving it from the database.
The Box class is likely the class you interact with most. As seen previously, you get Box instances via BoxStore.boxFor()
. A Box instance gives you access to objects of a particular type. For example, if you have User
and Order
entities, you need two Box objects to interact with each:
Box<User> userBox = boxStore.boxFor(User.class);Box<Order> orderBox = boxStore.boxFor(Order.class);
val userBox: Box<User> = ObjectBox.boxStore.boxFor()val orderBox: Box<Order> = ObjectBox.boxStore.boxFor()
These are some of the operations offered by the Box class:
put inserts a new or updates an existing object with the same ID. When inserting and put returns, an ID will be assigned to the just inserted object (this will be explained below). put
also supports putting multiple objects, which is more efficient.
User user = new User("Tina");userBox.put(user);​List<User> users = getNewUsers();userBox.put(users);
val user = User("Tina")userBox.put(user)​val users: List<User> = getNewUsers()userBox.put(users)
get and getAll: Given an object’s ID reads it back from its box. To get all objects in the box use getAll
.
User user = userBox.get(userId);​List<User> users = userBox.getAll();
val user = userBox[userId]​val users = userBox.all
query: Starts building a query to return objects from the box that match certain conditions. See queries for details.
List<User> results = userBox.query().equal(User_.name, "Tom").order(User_.name).build().find();
val results = userBox.query().equal(User_.name, "Tom").order(User_.name).build().find()
remove and removeAll: Remove a previously put object from its box (deletes it). remove
also supports removing multiple objects, which is more efficient. removeAll
removes (deletes) all objects in a box.
boolean isRemoved = userBox.remove(userId);​userBox.remove(users);// alternatively:userBox.removeByIds(userIds);​userBox.removeAll();
val isRemoved = userBox.remove(userId)​userBox.remove(users)// alternatively:userBox.removeByIds(userIds)​userBox.removeAll()
count: Returns the number of objects stored in this box.
long userCount = userBox.count();
val userCount = userBox.count()
For a complete list of methods available in the Box class, check the API reference documentation.
By default IDs for new objects are assigned by ObjectBox. When a new object is put, it will be assigned the next highest available ID:
User user = new User();// user.id == 0box.put(user);// user.id != 0long id = user.id;
val user = User()// user.id == 0box.put(user)// user.id != 0val id = user.id
For example, if there is an object with ID 1 and another with ID 100 in a box, the next new object that is put will be assigned ID 101.
If you try to assign a new ID yourself and put the object, ObjectBox will throw an error.
If you need to assign IDs by yourself have a look at how to switch to self-assigned IDs and what side-effects apply.
Object IDs can not be:
0
(zero) or null
(if using java.lang.Long) As said above, when putting an object with ID zero it will be assigned an unused ID (not zero).
0xFFFFFFFFFFFFFFFF
(-1 in Java) Reserved for internal use.
For a detailed explanation see the page on Object IDs.
While ObjectBox offers powerful transactions, it is sufficient for many apps to consider just some basics guidelines about transactions:
A put
runs an implicit transaction.
Prefer put
bulk overloads for lists (like put(entities)
) when possible.
For a high number of DB interactions in loops, consider explicit transactions, such as using runInTx()
.
For more details check the separate transaction documentation.
DaoCompat is a compatibility layer that gives you a greenDAO like API for ObjectBox. It makes switching from greenDAO to ObjectBox simple. Have a look at the documentation and the example. Contact us if you have any questions!
Check out the ObjectBox example projects on GitHub.