Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedded Objects #6713

Closed
RealmBot opened this issue Jan 7, 2020 · 1 comment
Closed

Embedded Objects #6713

RealmBot opened this issue Jan 7, 2020 · 1 comment
Assignees

Comments

@RealmBot
Copy link
Collaborator

RealmBot commented Jan 7, 2020

See RPM-72 for details.

@cmelchior
Copy link
Contributor

Semantics:
Embedded objects define how the object graph is serialized to MongoDB, e.g. embedded objects are embedded directly in the document (like a full JSON document instead of a link reference).

This has the following implications:

  • It defines ownership and thus cascading delete behavior. If the top-level object is deleted, all embedded objects under it are also deleted.
  • Only one parent can ever link to an embedded object. This needs to be enforced by the annotation processor and at runtime. This has implications on how
  • @PrimaryKey is not supported on embedded objects. Must be enforced by the annotation processor
  • Free-floating embedded objects with no parents are not possible. Must be enforced in the type system (new base class) or at runtime.

API Proposal 1

// New annotation, possible conflict with Room / JPA. Do we want to use it ourselves
// for type adapters? Can it be used for both?
@Embedded 
@RealmClass(embedded = true) // Alternative: Re-use existing annotation
open class Child : RealmObject() {

	// Throw schema error at compile time from the annotation processor
        // Embedded objects cannot have primary keys.
	@PrimaryKey
	var id: String

	// It is allowed to define one backlink to a parent
	// If only one @LinkingObjects is defined it doesn't have to be optional.
	@LinkingObjects // Automatically detect parent
	val parent: Parent
	@LinkingObjects("child") // Optional: manually name it property in parent
	val parent: Parent

	// If multiple parents exist. @LinkingObjects can still be used, but must be marked optional
	// As only one of them can be true
	@LinkingObjects
	val parent1: Parent?
	@LinkingObjects
	val parent2: OtherParent? 
}

// Usecase 1: Create Object
val lane = realm.createObject<Parent>() // Allowed with a null child
val task = realm.createObject<Child>() // Not allowed, runtime exception
// Could allow this, but this kind of override is already used for primary keys
// But perhaps the link can be seen as having primary key semantics. 
realm.createObject<Child>(managedParent); 

// Converting unmanaged objects -> managed works as before because we control order.
val lane = TaskLane(subTask = SubTask("task-name"))
realm.copyToRealm(lane)
realm.copyToRealmOrUpdate(lane)
realm.insert(lane)
realm.insertOrUpdate(lane)

// Usecase 2: "Move" an object. 
// This is really hard to support with current semantics and will feel really annoying
// Unsure exactly how to solve this unless we introduce even more complexity
// Because we can release without support for this and revisit once we get feedback
val lane1 = realm.where<TaskLane>().equalTo("id", 1).findFirst()
val lane2 = realm.where<TaskLane>().equalTo("id", 2).findFirst()

// Throws: SubTask cannot have more than one owner
lane2.subTask = lane1.subTask

// Explicit serialize/deserialize: Annyoing + expensive as well as being confusing if 
// embedded objects have links to normal Realm Objects.
val unmanagedTask = lane1.subTask.copyFromRealm(); 
lane1.subTask = null
lane2.subTask = unmanagedTask; // Does an implicit copy just like `list.add(item)` does

// Usecase 3: Deleting an embedded object. 
lane1.subTask.deleteFromRealm() // Just like today
lane1.subTask = null // Will also delete the object

// Usecase 4: Querying embedded objects just like today
val results: RealmResults<Child> = realm.where<Child>().beginsWith("name", "Test").findAll()

Advantages:

  • Reuse existing classes and annotations
  • Simplifies implementation

Disadvantages:

  • Introduce extra weird runtime exceptions (cannot create embedded objects directly).
  • Cannot move references easily.

@RealmBot RealmBot reopened this Jan 22, 2020
@RealmBot RealmBot closed this as completed Jun 9, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants