Entity Annotations in ObjectBox
Persisting objects with Entity Annotations in your iOS Swift application is easy with ObjectBox.
Database Persistence with Entity Annotations
ObjectBox DB persists Swift objects. For a clear distinction, we sometimes call those persistable objects "entities". To let ObjectBox know which classes are entities you can either make them implement the ObjectBox.Entity
protocol, or add annotations to them. Then ObjectBox can take care of your entities.
Here is an example:
The Entity annotation identifies the Swift class User
as a persistable entity. This will trigger ObjectBox to generate persistence code tailored for this class, even if it does not conform to the Entity
protocol..
Object IDs: id
While we recommend to define your ID as type Id
or EntityId<MyEntity>
(where MyEntity
would be replaced with the name of your class), you can also annotate a property of type UInt64
or Int64
as an ID.
ObjectBox will usually manage ID values for you, but should you absolutely need to, you can tell ObjectBox that you want to assign IDs manually by yourself by adding an "assignable" parameter to the id annotation:
If you do that, make sure that you assign a unique ID to each new object. If you assign the same ID to two objects of the same class, writing one to the database will overwrite the other. In general, it is best to let ObjectBox assign IDs. You are free to provide an additional indexed property to e.g. store a GUID for an object in addition to the ID used by ObjectBox, and to use queries to retrieve objects based on that GUID.
Ways to Define IDs
To specify Entity IDs, you need to have a property of type Id
. The code generator will look for one of these configurations, in the following order
A property that has a
// objectbox: id
comment annotation on the line above the property definition.A property named
var id: Id
.Any other property of the
Id
type, if there is only one.
Here's an example of using annotations in action:
Using Different Names in the Database than in Swift
The name
annotation lets you define a name on the database level for a property. This allows you to rename the Swift field without affecting the property name on the database level. This is mostly useful in cross-platform code, where different platforms may have different conventions for property names and you need to exchange database files between them.
Transient Properties
The // objectbox: transient
annotation can be used to mark properties that should not be persisted, like the temporary counter above. As far as ObjectBox is concerned, transient properties simply do not exist. static
properties are always ignored by ObjectBox and do not need to be marked as transient.
Property Indexes
Annotate a property with // objectbox: index
to create a database index for the corresponding database column. This can greatly improve performance when querying for that property.
Index is currently not supported for Data
, Float
and Double
An index stores additional information in the database to make lookups "faster", or more correctly, "more scalable". With an index, you will get results fast no matter if you store ten, one thousand, or one million objects in the database. Index based database lookups perform in O(log n).
As an analogy we could look at how you store objects in an Array<>
. For example you could store persons using an Array<Person>
. Now, you want to search for all persons with a specific name so you would iterate through the list and check for the name property of each object. This is an O(N) operation and thus does not scale well with an increasing number of objects.
To make this more scalable you can introduce a second data structure Dictionary<String, Person>
with the name as a key. This will give you a superfast lookup time (typically O(1)). The downside of this is that it needs more resources (here: RAM) and slows down add/remove operations on the list a bit. These principles can be transferred to database indexes, just that the primary resource consumed is disk space.
Index types (String)
Because String
properties typically take more space than scalar values, ObjectBox uses a hash for indexing strings by default. For any other type, the property value is used for all index look-ups.
You can instruct ObjectBox to use a value-based index for a String
property by specifying an index type:
Keep in mind that for String
, depending on the length of your values, a value-based index may require more storage space than the default hash-based index.
ObjectBox supports these index types:
Not specified Uses best index based on property type (
hash
forString
,value
for others).value Uses property values to build index. For
String,
this may require more storage than a hash-based index.hash Uses 32-bit hashes of property values to build the index. Occasional collisions may occur which should not have any performance impact in practice. Usually a better choice than hash64, as it requires less storage.
hash64 Uses 64-bit hashes of property values to build the index. Requires more storage than hash and thus should not be the first choice in most cases.
Vector Index for Nearest Neighbor Search
To enable nearest neighbor search, a special index type for vector properties is available:
Unique constraints
Annotate a property with unique
to enforce that values are unique before an entity is put:
A put()
operation will abort and throw an ObjectBoxError.uniqueViolation
error:
Converting Enums and Custom Types
Relations
Triggering generation
You usually should not need to do anything special to trigger code generation once your entity classes are properly annotated. The setup.rb
script should have automatically configured your project to run the code generator when you compile your project, for example using Product > Build in Xcode.
Last updated
Was this helpful?