If we have @Entity in Room in which there are complex objects as fields, we can use 2 approaches:
@Embedded - as I understand it, if you mark the field with this annotation, then Room will save all the fields that are inside the object as fields of the Entity itself, and then retrieve everything correctly.
@TypeConverters - here we write our own converter, which in most cases boils down to the usual parsing of an object into a Json string.
Actually the question:
What is the fundamental difference? Why not write @Embedded everywhere and not worry about converters? When is it better to write your own converter, and when is it better to use @Embedded, and what are the advantages and disadvantages of these approaches?
If we have @Entity in Room in which there are complex objects as fields, we can use 2 approaches
Actually there is one more approach to be mentioned here - is saving complex object in separate table and linking to it with foreign key (as usual id
with Int
or Long
type, often autogenerated).
User
and couple of another - UserGroup
(and field: user
) and Document
(field: author
). Using separate table User
you can change user's name only in one place and you don't need to touch two other tables (but you should do that with @Embedded
approach).Type-converter
- is converting type Date
to integer, since Sqlite doesn't know how to save this type using its own type's system. @Embedded
is not helpful in this case.Type-converter
- is persisting in database complex nested structures, often gotten from backend API (JSON serialisation). But this approach is fragile if you later decide to deal with part of these nested structures independently (query to them, for example).Type-converter
is persisting List or Array of some objects in one field. But often this approach could be replaced with using separate tables and foreign keys (if these objects form the List have its own value).@Embedded
on the same complex object it's a sign you should consider option with separate table and foreign key, since it's a waste of space and in some way violation of principles of DB tables' normalisation. For example, if some complex object has N fields and you use it as a @Embedded
field at two other tables that means that SQLite generates N additional columns in these two tables.@Embedded
is widely used in Room's data-classes with @Relation (ROOM's analogues for JOINs). There they are really helpful and help a lot to keep these data-classes' code short and simple. In that way @Embedded doesn't add any duplication to tables' structures (since it affects only on objects in memory) as it does when it's used inside class annotated with @Entity.