diff --git a/realm-annotations/src/main/java/io/realm/annotations/StrongRelationship.java b/realm-annotations/src/main/java/io/realm/annotations/StrongRelationship.java
new file mode 100644
index 0000000000..4089d98835
--- /dev/null
+++ b/realm-annotations/src/main/java/io/realm/annotations/StrongRelationship.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2017 Realm Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.realm.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation used to describe the relationship between two Realm model classes as Strong.
+ * If this annotation is not used the relationship is implicitly Weak.
+ *
+ * This annotation can only be applied to fields that reference other Realm model classes either
+ * using a differet reference or using a RealmList. It cannot be used on RealmLists containing
+ * primitive types nor on fields marked with {@link LinkingObjects}. The annotation processor will
+ * throw an error in that case.
+ *
+ * The relationship is determined pr. field, i.e. it is possible for an object A to have both a Weak
+ * and Strong relationship with object B if A contains multiple fields that reference B.
+ *
+ * A strong relationship between a parent object A and a child object B means B will automatically
+ * be deleted if A no longer holds a reference to B or if A is deleted itself. This is also known as
+ * cascading deletes.
+ *
+ * It is possible for multiple different classes to have a strong reference to the same object.
+ * In that case the child object is only deleted automatically when the last strong parent reference
+ * is removed or all parent objects are deleted.
+ *
+ * It is possible to create child objects (B) with no parents (A), these will only be deleted if
+ * an parent actually existed at some point, e.g. If A references B, then it is possible to
+ * create object B first and then later add the reference from A to B. B will only be
+ * automatically deleted when A either explicitly removes its reference or is deleted itself.
+ *
+ * Warning:
+ * Some special corner cases exists for cyclic object graphs that are strongly connected:
+ *
+ * -
+ * {@code ( A -> B <-> C )}:
+ * Object A contains a reference to B and C that in turn reference each other.
+ * If the reference between A and B is removed, then B and C are an "disconnected island".
+ * In this case neither B nor C will be deleted automatically and this must be done
+ * manually.
+ *
+ * -
+ * {@code ( A <-> B )}:
+ * Object A and Object B strongly references each other in isolation.
+ * If either A or B breaks the reference so the graph becomes {@code (A -> B)} or
+ * {@code (B -> A)}, then both A and B is deleted. It is possible to avoid this
+ * behaviour by adding an outside strong reference, so the graph becomes:
+ * {@code ( C - > A <-> B )}.
+ *
+ *
+ *
+ * Example:
+ * {@code
+ * public class Person extends RealmObject {
+ *
+ * public String name;
+ *
+ * // The ContactInfo object is deleted when the person is.
+ * \@StrongRelationship
+ * public ContactInfo contactInfo;
+ *
+ * // Is implicitly weak. The Dog objects will not be deleted when the person is.
+ * public RealmList dogs = new RealmList<>();
+ * }
+ * }
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface StrongRelationship {
+}
\ No newline at end of file
diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java
index 8292873163..3509cf3ce3 100644
--- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java
+++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java
@@ -48,6 +48,7 @@
import io.realm.annotations.RealmField;
import io.realm.annotations.RealmNamingPolicy;
import io.realm.annotations.Required;
+import io.realm.annotations.StrongRelationship;
import io.realm.processor.nameconverter.NameConverter;
@@ -65,7 +66,7 @@ public class ClassMetaData {
private final Set backlinks = new HashSet();
private final Set nullableFields = new HashSet(); // Set of fields which can be nullable
private final Set nullableValueListFields = new HashSet(); // Set of fields whose elements can be nullable
-
+ private final Set strongReferences = new HashSet<>(); // Set of fields whose elements have strong references
private String packageName; // package name for model class.
private boolean hasDefaultConstructor; // True if model has a public no-arg constructor.
private VariableElement primaryKey; // Reference to field used as primary key, if any.
@@ -171,6 +172,10 @@ public Set getBacklinkFields() {
return Collections.unmodifiableSet(backlinks);
}
+ public boolean isStrongReference(VariableElement field) {
+ return strongReferences.contains(field);
+ }
+
public String getInternalGetter(String fieldName) {
return "realmGet$" + fieldName;
}
@@ -556,11 +561,20 @@ private boolean categorizeField(Element element) {
}
}
+ // Check that @RealmField is used on the correct fields.
+ if (field.getAnnotation(StrongRelationship.class) != null) {
+ if (!Utils.isRealmModel(field) && !Utils.isRealmModelList(field)) {
+ Utils.error("@RealmField is only allowed on fields that reference either other Realm model classes or lists of model classes.");
+ return false;
+ }
+ strongReferences.add(field);
+ }
+
if (field.getAnnotation(PrimaryKey.class) != null) {
if (!categorizePrimaryKeyField(field)) { return false; }
}
- // @LinkingObjects cannot be @PrimaryKey or @Index.
+ // @LinkingObjects cannot be a Strong reference, @PrimaryKey or @Index.
if (field.getAnnotation(LinkingObjects.class) != null) {
// Do not add backlinks to fields list.
return categorizeBacklinkField(field);
diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java
index ef1e771df3..e62dbb697b 100644
--- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java
+++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java
@@ -746,15 +746,15 @@ private void emitCreateExpectedObjectSchemaInfo(JavaWriter writer) throws IOExce
case OBJECT: {
String fieldTypeQualifiedName = Utils.getFieldTypeQualifiedName(field);
String internalClassName = Utils.getReferencedTypeInternalClassNameStatement(fieldTypeQualifiedName, classCollection);
- writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.OBJECT, %s)",
- fieldName, internalClassName);
+ writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.OBJECT, %s, %s)",
+ fieldName, internalClassName, metadata.isStrongReference(field));
break;
}
case LIST: {
String genericTypeQualifiedName = Utils.getGenericTypeQualifiedName(field);
String internalClassName = Utils.getReferencedTypeInternalClassNameStatement(genericTypeQualifiedName, classCollection);
- writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.LIST, %s)",
- fieldName, internalClassName);
+ writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.LIST, %s, %s)",
+ fieldName, internalClassName, metadata.isStrongReference(field));
break;
}
case INTEGER_LIST:
diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/some_test_AllTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/some_test_AllTypesRealmProxy.java
index ee1fccac5a..bd23cb2a6c 100644
--- a/realm/realm-annotations-processor/src/test/resources/io/realm/some_test_AllTypesRealmProxy.java
+++ b/realm/realm-annotations-processor/src/test/resources/io/realm/some_test_AllTypesRealmProxy.java
@@ -840,8 +840,8 @@ private static OsObjectSchemaInfo createExpectedObjectSchemaInfo() {
builder.addPersistedProperty("columnDate", RealmFieldType.DATE, !Property.PRIMARY_KEY, !Property.INDEXED, Property.REQUIRED);
builder.addPersistedProperty("columnBinary", RealmFieldType.BINARY, !Property.PRIMARY_KEY, !Property.INDEXED, Property.REQUIRED);
builder.addPersistedProperty("columnMutableRealmInteger", RealmFieldType.INTEGER, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED);
- builder.addPersistedLinkProperty("columnObject", RealmFieldType.OBJECT, "AllTypes");
- builder.addPersistedLinkProperty("columnRealmList", RealmFieldType.LIST, "AllTypes");
+ builder.addPersistedLinkProperty("columnObject", RealmFieldType.OBJECT, "AllTypes", false);
+ builder.addPersistedLinkProperty("columnRealmList", RealmFieldType.LIST, "AllTypes", false);
builder.addPersistedValueListProperty("columnStringList", RealmFieldType.STRING_LIST, !Property.REQUIRED);
builder.addPersistedValueListProperty("columnBinaryList", RealmFieldType.BINARY_LIST, !Property.REQUIRED);
builder.addPersistedValueListProperty("columnBooleanList", RealmFieldType.BOOLEAN_LIST, !Property.REQUIRED);
diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/some_test_NullTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/some_test_NullTypesRealmProxy.java
index 1e5c65b4a4..ec1968dc51 100644
--- a/realm/realm-annotations-processor/src/test/resources/io/realm/some_test_NullTypesRealmProxy.java
+++ b/realm/realm-annotations-processor/src/test/resources/io/realm/some_test_NullTypesRealmProxy.java
@@ -1671,7 +1671,7 @@ private static OsObjectSchemaInfo createExpectedObjectSchemaInfo() {
builder.addPersistedProperty("fieldDoubleNull", RealmFieldType.DOUBLE, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED);
builder.addPersistedProperty("fieldDateNotNull", RealmFieldType.DATE, !Property.PRIMARY_KEY, !Property.INDEXED, Property.REQUIRED);
builder.addPersistedProperty("fieldDateNull", RealmFieldType.DATE, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED);
- builder.addPersistedLinkProperty("fieldObjectNull", RealmFieldType.OBJECT, "NullTypes");
+ builder.addPersistedLinkProperty("fieldObjectNull", RealmFieldType.OBJECT, "NullTypes", false);
builder.addPersistedValueListProperty("fieldStringListNotNull", RealmFieldType.STRING_LIST, Property.REQUIRED);
builder.addPersistedValueListProperty("fieldStringListNull", RealmFieldType.STRING_LIST, !Property.REQUIRED);
builder.addPersistedValueListProperty("fieldBinaryListNotNull", RealmFieldType.BINARY_LIST, Property.REQUIRED);
diff --git a/realm/realm-library/src/androidTest/java/io/realm/LinkingObjectsManagedTests.java b/realm/realm-library/src/androidTest/java/io/realm/LinkingObjectsManagedTests.java
index ef0e68ffbc..c77fc8dfca 100644
--- a/realm/realm-library/src/androidTest/java/io/realm/LinkingObjectsManagedTests.java
+++ b/realm/realm-library/src/androidTest/java/io/realm/LinkingObjectsManagedTests.java
@@ -599,7 +599,7 @@ public void migration_backlinkedSourceFieldDoesntExist() throws ClassNotFoundExc
.build();
OsObjectSchemaInfo sourceSchemaInfo = new OsObjectSchemaInfo.Builder("BacklinksSource", 2, 0)
.addPersistedProperty("name", RealmFieldType.STRING, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED)
- .addPersistedLinkProperty("child", RealmFieldType.OBJECT, "BacklinksTarget")
+ .addPersistedLinkProperty("child", RealmFieldType.OBJECT, "BacklinksTarget", false)
.build();
Map, OsObjectSchemaInfo> infoMap =
new HashMap, OsObjectSchemaInfo>();
@@ -643,7 +643,7 @@ public void migration_backlinkedSourceFieldWrongType() {
OsObjectSchemaInfo sourceSchemaInfo = new OsObjectSchemaInfo.Builder("BacklinksSource", 2, 0)
.addPersistedProperty("name", RealmFieldType.STRING, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED)
.addPersistedLinkProperty("child", RealmFieldType.OBJECT,
- "BacklinksSource"/*"BacklinksTarget" is the original value*/)
+ "BacklinksSource"/*"BacklinksTarget" is the original value*/, false)
.build();
Map, OsObjectSchemaInfo> infoMap =
new HashMap, OsObjectSchemaInfo>();
diff --git a/realm/realm-library/src/androidTest/java/io/realm/RelationshipTests.java b/realm/realm-library/src/androidTest/java/io/realm/RelationshipTests.java
new file mode 100644
index 0000000000..2e57b69ad4
--- /dev/null
+++ b/realm/realm-library/src/androidTest/java/io/realm/RelationshipTests.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2018 Realm Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.realm;
+
+
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import io.realm.entities.RelationshipChild;
+import io.realm.entities.RelationshipParent;
+import io.realm.rule.TestRealmConfigurationFactory;
+
+import static org.junit.Assert.assertEquals;
+
+
+/**
+ * Testing Strong/Weak leaks. This should already be tested in ObjectStore/Core, so just doing
+ * smoke test here for the most common scenarios.
+ */
+@RunWith(AndroidJUnit4.class)
+public class RelationshipTests {
+
+ @Rule
+ public final TestRealmConfigurationFactory configFactory = new TestRealmConfigurationFactory();
+
+ private RealmConfiguration realmConfig;
+ private Realm realm;
+
+ @Before
+ public void setUp() {
+ realmConfig = configFactory.createConfiguration();
+ realm = Realm.getInstance(realmConfig);
+ realm.beginTransaction();
+ }
+
+ @After
+ public void tearDown() {
+ if (realm != null && !realm.isClosed()) {
+ realm.cancelTransaction();
+ realm.close();
+ }
+ }
+
+ @Test
+ public void cascadeDeleteStrongObjectReference() {
+ RealmResults children = realm.where(RelationshipChild.class).findAll();
+
+ // Create Strong relationship
+ RelationshipChild child = realm.createObject(RelationshipChild.class);
+ child.name = "Child";
+ RelationshipParent parent = realm.createObject(RelationshipParent.class);
+ parent.strongObjectRef = child;
+
+ // Delete parent
+ assertEquals(1, children.size());
+ parent.deleteFromRealm();
+ assertEquals(0, children.size());
+ }
+
+ @Test
+ public void dontCascadeDeleteWeakObjectReference() {
+ RealmResults children = realm.where(RelationshipChild.class).findAll();
+
+ // Create Strong relationship
+ RelationshipChild child = realm.createObject(RelationshipChild.class);
+ child.name = "Child";
+ RelationshipParent parent = realm.createObject(RelationshipParent.class);
+ parent.weakObjectRef = child;
+
+ // Delete parent
+ assertEquals(1, children.size());
+ parent.deleteFromRealm();
+ assertEquals(1, children.size());
+ }
+
+ @Test
+ public void cascadeDeleteStrongListReference() {
+ int TEST_SIZE = 10;
+ RealmResults children = realm.where(RelationshipChild.class).findAll();
+
+ // Create Strong relationship
+ RelationshipParent parent = realm.createObject(RelationshipParent.class);
+ for (int i = 0; i < TEST_SIZE; i++) {
+ parent.strongListRef.add(new RelationshipChild("child " + i));
+ }
+
+ // Delete parent
+ assertEquals(TEST_SIZE, children.size());
+ parent.deleteFromRealm();
+ assertEquals(0, children.size());
+ }
+
+ @Test
+ public void dontCascadeDeleteWeakListReference() {
+ int TEST_SIZE = 10;
+ RealmResults children = realm.where(RelationshipChild.class).findAll();
+
+ // Create Strong relationship
+ RelationshipParent parent = realm.createObject(RelationshipParent.class);
+ for (int i = 0; i < TEST_SIZE; i++) {
+ parent.weakListRef.add(new RelationshipChild("child " + i));
+ }
+
+ // Delete parent
+ assertEquals(TEST_SIZE, children.size());
+ parent.deleteFromRealm();
+ assertEquals(TEST_SIZE, children.size());
+ }
+
+ @Test
+ public void cascadeWhenFinalStrongReferenceIsGone() {
+ RealmResults children = realm.where(RelationshipChild.class).findAll();
+
+ // Create Strong relationship
+ RelationshipChild child = realm.createObject(RelationshipChild.class);
+ child.name = "Child";
+ RelationshipParent parent1 = realm.createObject(RelationshipParent.class);
+ parent1.strongObjectRef = child;
+ RelationshipParent parent2 = realm.createObject(RelationshipParent.class);
+ parent2.strongObjectRef = child;
+
+ assertEquals(1, children.size());
+ parent1.deleteFromRealm();
+ assertEquals(1, children.size());
+ parent2.deleteFromRealm();
+ assertEquals(0, children.size());
+ }
+
+}
\ No newline at end of file
diff --git a/realm/realm-library/src/androidTest/java/io/realm/entities/RelationshipChild.java b/realm/realm-library/src/androidTest/java/io/realm/entities/RelationshipChild.java
new file mode 100644
index 0000000000..3ee3f9ef7e
--- /dev/null
+++ b/realm/realm-library/src/androidTest/java/io/realm/entities/RelationshipChild.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018 Realm Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.realm.entities;
+
+import io.realm.RealmObject;
+
+public class RelationshipChild extends RealmObject {
+
+ public String name;
+
+ public RelationshipChild() {
+ }
+
+ public RelationshipChild(String name) {
+ this.name = name;
+ }
+}
diff --git a/realm/realm-library/src/androidTest/java/io/realm/entities/RelationshipParent.java b/realm/realm-library/src/androidTest/java/io/realm/entities/RelationshipParent.java
new file mode 100644
index 0000000000..7ce477a5d8
--- /dev/null
+++ b/realm/realm-library/src/androidTest/java/io/realm/entities/RelationshipParent.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018 Realm Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.realm.entities;
+
+import io.realm.RealmList;
+import io.realm.RealmObject;
+import io.realm.annotations.StrongRelationship;
+
+public class RelationshipParent extends RealmObject {
+
+ @StrongRelationship
+ public RelationshipChild strongObjectRef;
+
+ public RelationshipChild weakObjectRef;
+
+ @StrongRelationship
+ public RealmList strongListRef = new RealmList<>();
+
+ public RealmList weakListRef = new RealmList<>();
+
+}
diff --git a/realm/realm-library/src/main/cpp/io_realm_internal_Property.cpp b/realm/realm-library/src/main/cpp/io_realm_internal_Property.cpp
index 8362e7c559..c8003a6634 100644
--- a/realm/realm-library/src/main/cpp/io_realm_internal_Property.cpp
+++ b/realm/realm-library/src/main/cpp/io_realm_internal_Property.cpp
@@ -70,14 +70,16 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_Property_nativeCreatePersistedPro
JNIEXPORT jlong JNICALL Java_io_realm_internal_Property_nativeCreatePersistedLinkProperty(JNIEnv* env, jclass,
jstring j_name_str,
jint type,
- jstring j_target_class_name)
+ jstring j_target_class_name,
+ jboolean is_strong_reference)
{
TR_ENTER()
try {
JStringAccessor name(env, j_name_str);
JStringAccessor link_name(env, j_target_class_name);
PropertyType p_type = static_cast(static_cast(type));
- return reinterpret_cast(new Property(name, p_type, link_name));
+ Relationship relationship = (is_strong_reference) ? Relationship::Strong : Relationship::Weak;
+ return reinterpret_cast(new Property(name, p_type, link_name, relationship));
}
CATCH_STD()
return 0;
diff --git a/realm/realm-library/src/main/cpp/jni_util/log.hpp b/realm/realm-library/src/main/cpp/jni_util/log.hpp
index db61e5fc7a..a2ab5448f1 100644
--- a/realm/realm-library/src/main/cpp/jni_util/log.hpp
+++ b/realm/realm-library/src/main/cpp/jni_util/log.hpp
@@ -27,7 +27,6 @@
#include "io_realm_log_LogLevel.h"
#include "realm/util/logger.hpp"
-
#define TR_ENTER() \
if (realm::jni_util::Log::s_level <= realm::jni_util::Log::trace) { \
realm::jni_util::Log::t(" --> %1", __FUNCTION__); \
diff --git a/realm/realm-library/src/main/cpp/object-store b/realm/realm-library/src/main/cpp/object-store
index f2a536d29d..ccf2d9b6ff 160000
--- a/realm/realm-library/src/main/cpp/object-store
+++ b/realm/realm-library/src/main/cpp/object-store
@@ -1 +1 @@
-Subproject commit f2a536d29de48e34e60799a5bf3f36e13806387e
+Subproject commit ccf2d9b6ff6d8182da2768d487080536b23c95ba
diff --git a/realm/realm-library/src/main/cpp/util.hpp b/realm/realm-library/src/main/cpp/util.hpp
index 42071658f0..d92b30da06 100644
--- a/realm/realm-library/src/main/cpp/util.hpp
+++ b/realm/realm-library/src/main/cpp/util.hpp
@@ -31,8 +31,8 @@
#include
#include
#include
-#include "io_realm_internal_Util.h"
+#include "io_realm_internal_Util.h"
#include "java_exception_def.hpp"
#include "jni_util/log.hpp"
#include "jni_util/java_exception_thrower.hpp"
diff --git a/realm/realm-library/src/main/java/io/realm/internal/OsObjectSchemaInfo.java b/realm/realm-library/src/main/java/io/realm/internal/OsObjectSchemaInfo.java
index cac92e21df..74e2403a08 100644
--- a/realm/realm-library/src/main/java/io/realm/internal/OsObjectSchemaInfo.java
+++ b/realm/realm-library/src/main/java/io/realm/internal/OsObjectSchemaInfo.java
@@ -90,9 +90,12 @@ public Builder addPersistedValueListProperty(String name, RealmFieldType type, b
* {@link RealmFieldType#LIST}.
* @return this {@code OsObjectSchemaInfo.Builder}.
*/
- public Builder addPersistedLinkProperty(String name, RealmFieldType type, String linkedClassName) {
+ public Builder addPersistedLinkProperty(String name,
+ RealmFieldType type,
+ String linkedClassName,
+ boolean isStrongRelationship) {
long propertyPtr = Property.nativeCreatePersistedLinkProperty(name,
- Property.convertFromRealmFieldType(type, false), linkedClassName);
+ Property.convertFromRealmFieldType(type, false), linkedClassName, isStrongRelationship);
persistedPropertyPtrArray[persistedPropertyPtrCurPos] = propertyPtr;
persistedPropertyPtrCurPos++;
return this;
diff --git a/realm/realm-library/src/main/java/io/realm/internal/Property.java b/realm/realm-library/src/main/java/io/realm/internal/Property.java
index 0bcff85f24..d13d89b98a 100644
--- a/realm/realm-library/src/main/java/io/realm/internal/Property.java
+++ b/realm/realm-library/src/main/java/io/realm/internal/Property.java
@@ -210,7 +210,7 @@ public long getNativeFinalizerPtr() {
static native long nativeCreatePersistedProperty(
String name, int type, boolean isPrimary, boolean isIndexed);
- static native long nativeCreatePersistedLinkProperty(String name, int type, String linkedToName);
+ static native long nativeCreatePersistedLinkProperty(String name, int type, String linkedToName, boolean isStrongRelationship);
static native long nativeCreateComputedLinkProperty(
String name, String sourceClassName, String sourceFieldName);