From 1226f26afe8cd50841113f8c7aa9a042cc697c83 Mon Sep 17 00:00:00 2001 From: Christian Melchior Date: Fri, 12 Jan 2018 08:38:13 +0100 Subject: [PATCH 1/5] Upgrade to Sync 2.2.9 --- CHANGELOG.md | 4 ++++ dependencies.list | 6 +++--- .../src/main/cpp/io_realm_internal_OsObject.cpp | 2 +- .../main/cpp/io_realm_internal_OsRealmConfig.cpp | 2 +- .../main/cpp/io_realm_internal_OsSchemaInfo.cpp | 2 +- .../src/main/cpp/io_realm_internal_Table.cpp | 2 +- .../realm-library/src/main/cpp/java_accessor.hpp | 4 ++-- .../src/main/cpp/java_sort_descriptor.hpp | 2 -- .../src/main/cpp/jni_impl/android_logger.cpp | 2 +- .../main/cpp/jni_util/java_exception_thrower.cpp | 2 +- realm/realm-library/src/main/cpp/jni_util/log.hpp | 15 ++++++++------- realm/realm-library/src/main/cpp/object-store | 2 +- realm/realm-library/src/main/cpp/util.hpp | 2 +- 13 files changed, 25 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df4a90869d..3133d7f865 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ * Throws a better exception message when calling `RealmObjectSchema.addField()` with a `RealmModel` class (#3388). * Use https for Realm version checker (#4043). +### Internal + +* Upgraded to Realm Sync 2.2.9 +* Upgraded to Realm Core 5.1.2 ## 4.3.1 (2017-12-06) diff --git a/dependencies.list b/dependencies.list index 3703b72124..e137ca9248 100644 --- a/dependencies.list +++ b/dependencies.list @@ -1,9 +1,9 @@ # Realm Sync Core release used by Realm Java # https://github.com/realm/realm-sync/releases -REALM_SYNC_VERSION=2.1.8 -REALM_SYNC_SHA256=14e4aabe270638aa96f84396be27985b6809e532183035c5150dd2933d676248 +REALM_SYNC_VERSION=2.2.9 +REALM_SYNC_SHA256=d770d639d2b187c15e6d0bc798b909f5b424d61444f1f83f9e56f5be43e96afc # Object Server Release used by Integration tests. Installed using NPM. # Use `npm view realm-object-server versions` to get a list of available versions. -REALM_OBJECT_SERVER_DE_VERSION=2.1.0 +REALM_OBJECT_SERVER_DE_VERSION=2.5.1 diff --git a/realm/realm-library/src/main/cpp/io_realm_internal_OsObject.cpp b/realm/realm-library/src/main/cpp/io_realm_internal_OsObject.cpp index 3099c70d56..d7e8811353 100644 --- a/realm/realm-library/src/main/cpp/io_realm_internal_OsObject.cpp +++ b/realm/realm-library/src/main/cpp/io_realm_internal_OsObject.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include "util.hpp" #include "java_class_global_def.hpp" diff --git a/realm/realm-library/src/main/cpp/io_realm_internal_OsRealmConfig.cpp b/realm/realm-library/src/main/cpp/io_realm_internal_OsRealmConfig.cpp index 1da13db3ce..928e244ca5 100644 --- a/realm/realm-library/src/main/cpp/io_realm_internal_OsRealmConfig.cpp +++ b/realm/realm-library/src/main/cpp/io_realm_internal_OsRealmConfig.cpp @@ -362,7 +362,7 @@ JNIEXPORT void JNICALL Java_io_realm_internal_OsRealmConfig_nativeSetSyncConfigS "(Ljava/lang/String;Ljava/lang/String;I)Z", true); std::function ssl_verify_callback = - [](const std::string server_address, REALM_UNUSED realm::sync::Client::port_type server_port, + [](const std::string server_address, REALM_UNUSED realm::sync::Session::port_type server_port, const char* pem_data, size_t pem_size, REALM_UNUSED int preverify_ok, int depth) { Log::d("Callback to Java requesting certificate validation for host %1", diff --git a/realm/realm-library/src/main/cpp/io_realm_internal_OsSchemaInfo.cpp b/realm/realm-library/src/main/cpp/io_realm_internal_OsSchemaInfo.cpp index 0f428436a7..07f05e9342 100644 --- a/realm/realm-library/src/main/cpp/io_realm_internal_OsSchemaInfo.cpp +++ b/realm/realm-library/src/main/cpp/io_realm_internal_OsSchemaInfo.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include "java_accessor.hpp" #include "java_exception_def.hpp" diff --git a/realm/realm-library/src/main/cpp/io_realm_internal_Table.cpp b/realm/realm-library/src/main/cpp/io_realm_internal_Table.cpp index 1618c48ad9..2096f2d3a2 100644 --- a/realm/realm-library/src/main/cpp/io_realm_internal_Table.cpp +++ b/realm/realm-library/src/main/cpp/io_realm_internal_Table.cpp @@ -21,7 +21,7 @@ #include "io_realm_internal_Table.h" #include "shared_realm.hpp" -#include "util/format.hpp" +#include #include "java_accessor.hpp" #include "java_exception_def.hpp" diff --git a/realm/realm-library/src/main/cpp/java_accessor.hpp b/realm/realm-library/src/main/cpp/java_accessor.hpp index 333f77a3f4..9e1f234e97 100644 --- a/realm/realm-library/src/main/cpp/java_accessor.hpp +++ b/realm/realm-library/src/main/cpp/java_accessor.hpp @@ -26,8 +26,8 @@ #include #include -#include -#include +#include +#include #include "java_class_global_def.hpp" #include "java_exception_def.hpp" diff --git a/realm/realm-library/src/main/cpp/java_sort_descriptor.hpp b/realm/realm-library/src/main/cpp/java_sort_descriptor.hpp index 81384f9a15..92893bdca0 100644 --- a/realm/realm-library/src/main/cpp/java_sort_descriptor.hpp +++ b/realm/realm-library/src/main/cpp/java_sort_descriptor.hpp @@ -19,8 +19,6 @@ #include -#include "descriptor_ordering.hpp" - namespace realm { namespace jni_util { diff --git a/realm/realm-library/src/main/cpp/jni_impl/android_logger.cpp b/realm/realm-library/src/main/cpp/jni_impl/android_logger.cpp index 8e3972aea0..28b1a1262f 100644 --- a/realm/realm-library/src/main/cpp/jni_impl/android_logger.cpp +++ b/realm/realm-library/src/main/cpp/jni_impl/android_logger.cpp @@ -16,7 +16,7 @@ #include -#include "util/format.hpp" +#include #include "android_logger.hpp" diff --git a/realm/realm-library/src/main/cpp/jni_util/java_exception_thrower.cpp b/realm/realm-library/src/main/cpp/jni_util/java_exception_thrower.cpp index 6278fd7fb8..82f6c13ebc 100644 --- a/realm/realm-library/src/main/cpp/jni_util/java_exception_thrower.cpp +++ b/realm/realm-library/src/main/cpp/jni_util/java_exception_thrower.cpp @@ -17,7 +17,7 @@ #include "java_exception_thrower.hpp" #include "log.hpp" -#include +#include using namespace realm::util; using namespace realm::jni_util; 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 98cc58d1c9..db4618601f 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,8 @@ #include "io_realm_log_LogLevel.h" #include "realm/util/logger.hpp" -#include "util/format.hpp" + +#include #define TR_ENTER() \ if (realm::jni_util::Log::s_level <= realm::jni_util::Log::trace) { \ @@ -114,32 +115,32 @@ class Log { template inline static void t(const char* fmt, Args&&... args) { - shared().log(trace, REALM_JNI_TAG, nullptr, _impl::format(fmt, {_impl::Printable(args)...}).c_str()); + shared().log(trace, REALM_JNI_TAG, nullptr, util::format(fmt, {util::Printable(args)...}).c_str()); } template inline static void d(const char* fmt, Args&&... args) { - shared().log(debug, REALM_JNI_TAG, nullptr, _impl::format(fmt, {_impl::Printable(args)...}).c_str()); + shared().log(debug, REALM_JNI_TAG, nullptr, util::format(fmt, {util::Printable(args)...}).c_str()); } template inline static void i(const char* fmt, Args&&... args) { - shared().log(info, REALM_JNI_TAG, nullptr, _impl::format(fmt, {_impl::Printable(args)...}).c_str()); + shared().log(info, REALM_JNI_TAG, nullptr, util::format(fmt, {util::Printable(args)...}).c_str()); } template inline static void w(const char* fmt, Args&&... args) { - shared().log(warn, REALM_JNI_TAG, nullptr, _impl::format(fmt, {_impl::Printable(args)...}).c_str()); + shared().log(warn, REALM_JNI_TAG, nullptr, util::format(fmt, {util::Printable(args)...}).c_str()); } template inline static void e(const char* fmt, Args&&... args) { - shared().log(error, REALM_JNI_TAG, nullptr, _impl::format(fmt, {_impl::Printable(args)...}).c_str()); + shared().log(error, REALM_JNI_TAG, nullptr, util::format(fmt, {util::Printable(args)...}).c_str()); } template inline static void f(const char* fmt, Args&&... args) { - shared().log(fatal, REALM_JNI_TAG, nullptr, _impl::format(fmt, {_impl::Printable(args)...}).c_str()); + shared().log(fatal, REALM_JNI_TAG, nullptr, util::format(fmt, {util::Printable(args)...}).c_str()); } static realm::util::RootLogger::Level convert_to_core_log_level(Level level); diff --git a/realm/realm-library/src/main/cpp/object-store b/realm/realm-library/src/main/cpp/object-store index 2b7db38bd1..8517ee7f43 160000 --- a/realm/realm-library/src/main/cpp/object-store +++ b/realm/realm-library/src/main/cpp/object-store @@ -1 +1 @@ -Subproject commit 2b7db38bd112c82c55a0fa4bbecd24f652d45ba1 +Subproject commit 8517ee7f4378fe0f54945b3e4973766ff65e455d diff --git a/realm/realm-library/src/main/cpp/util.hpp b/realm/realm-library/src/main/cpp/util.hpp index 21bb35c354..8123e33469 100644 --- a/realm/realm-library/src/main/cpp/util.hpp +++ b/realm/realm-library/src/main/cpp/util.hpp @@ -32,7 +32,7 @@ #include #include -#include +#include #include "io_realm_internal_Util.h" From 69ede81dfaf5eefdaaf638c17f69639986a09733 Mon Sep 17 00:00:00 2001 From: Christian Melchior Date: Fri, 12 Jan 2018 10:50:42 +0100 Subject: [PATCH 2/5] Add support for Weak/Strong links --- .../io/realm/annotations/Relationship.java | 57 +++++++ .../realm/annotations/RelationshipType.java | 73 +++++++++ .../io/realm/processor/ClassMetaData.java | 23 ++- .../io/realm/processor/RealmProcessor.java | 1 + .../processor/RealmProxyClassGenerator.java | 8 +- .../io/realm/AllTypesRealmProxy.java | 4 +- .../io/realm/NullTypesRealmProxy.java | 2 +- .../io/realm/LinkingObjectsManagedTests.java | 4 +- .../java/io/realm/RelationshipTests.java | 148 ++++++++++++++++++ .../io/realm/entities/RelationshipChild.java | 30 ++++ .../io/realm/entities/RelationshipParent.java | 35 +++++ .../main/cpp/io_realm_internal_Property.cpp | 3 +- realm/realm-library/src/main/cpp/object-store | 2 +- .../io/realm/internal/OsObjectSchemaInfo.java | 8 +- .../main/java/io/realm/internal/Property.java | 2 +- 15 files changed, 384 insertions(+), 16 deletions(-) create mode 100644 realm-annotations/src/main/java/io/realm/annotations/Relationship.java create mode 100644 realm-annotations/src/main/java/io/realm/annotations/RelationshipType.java create mode 100644 realm/realm-library/src/androidTest/java/io/realm/RelationshipTests.java create mode 100644 realm/realm-library/src/androidTest/java/io/realm/entities/RelationshipChild.java create mode 100644 realm/realm-library/src/androidTest/java/io/realm/entities/RelationshipParent.java diff --git a/realm-annotations/src/main/java/io/realm/annotations/Relationship.java b/realm-annotations/src/main/java/io/realm/annotations/Relationship.java new file mode 100644 index 0000000000..27d98cbadc --- /dev/null +++ b/realm-annotations/src/main/java/io/realm/annotations/Relationship.java @@ -0,0 +1,57 @@ +/* + * 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 objects through either a object or list + * reference. See {@link RelationshipType} for a detailed description of the semantics of setting this. + *

+ * This annotation can only be applied to fields that reference either an object or a RealmList with + * model classes: + * {@code + * public class Person extends RealmObject { + * + * public String name; + * + * \@Relationship(RelationshipType.STRONG) + * public ContactInfo contactInfo; + * + * \@Relationship(RelationshipType.WEAK) + * public RealmList dogs = new RealmList<>(); + * } + * } + * + * In all other cases the annotation processor will throw an error. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@Inherited +public @interface Relationship { + + /** + * Set the type of the relationship. See {@link RelationshipType} for more information about the + * semantics. + */ + RelationshipType value() default RelationshipType.WEAK; +} \ No newline at end of file diff --git a/realm-annotations/src/main/java/io/realm/annotations/RelationshipType.java b/realm-annotations/src/main/java/io/realm/annotations/RelationshipType.java new file mode 100644 index 0000000000..a775bf4c91 --- /dev/null +++ b/realm-annotations/src/main/java/io/realm/annotations/RelationshipType.java @@ -0,0 +1,73 @@ +/* + * 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.annotations; + +/** + * Enum describing what kind of relationship exists between two Realm model classes A and B. A + * relationship can either be {@link #WEAK} or {@link #STRONG}. + * + * 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. + */ +public enum RelationshipType { + /** + * Indicates that the relationship between object A and B is strong. This means that B + * will be deleted automatically 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 object is only deleted automatically when the last strong 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 )}. + *
  • + *
+ */ + STRONG, + + /** + * Indicates that the relationship between object A and B is weak. This means that A and B + * can exist independently regardless of what happens to the other. + *

+ * This is the default relationship type between objects. + *

+ * Fields marked with {@link LinkingObjects} is always considered to have a weak relationship. + *

+ */ + WEAK, +} 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 cb8b7a54c7..e12e5e92bc 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 @@ -44,6 +44,8 @@ import io.realm.annotations.Index; import io.realm.annotations.LinkingObjects; import io.realm.annotations.PrimaryKey; +import io.realm.annotations.Relationship; +import io.realm.annotations.RelationshipType; import io.realm.annotations.Required; @@ -60,7 +62,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. @@ -145,6 +147,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; } @@ -487,11 +493,24 @@ private boolean categorizeField(Element element) { } } + // Check that @RealmField is used on the correct fields. + if (field.getAnnotation(Relationship.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; + } + + RelationshipType relationship = field.getAnnotation(Relationship.class).value(); + if (relationship == RelationshipType.STRONG) { + 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/RealmProcessor.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProcessor.java index 713ab6b2ef..4e3d9eff3a 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProcessor.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProcessor.java @@ -119,6 +119,7 @@ */ @SupportedAnnotationTypes({ "io.realm.annotations.RealmClass", + "io.realm.annotations.RealmField", "io.realm.annotations.Ignore", "io.realm.annotations.Index", "io.realm.annotations.PrimaryKey", 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 6faacbfa29..293e07c428 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 @@ -748,15 +748,15 @@ private void emitCreateExpectedObjectSchemaInfo(JavaWriter writer) throws IOExce case OBJECT: String fieldTypeSimpleName = Utils.getFieldTypeSimpleName(field); - writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.OBJECT, \"%s\")", - fieldName, fieldTypeSimpleName); + writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.OBJECT, \"%s\", %s)", + fieldName, fieldTypeSimpleName, metadata.isStrongReference(field)); break; case LIST: // only for model list. String genericTypeSimpleName = Utils.getGenericTypeSimpleName(field); - writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.LIST, \"%s\")", - fieldName, genericTypeSimpleName); + writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.LIST, \"%s\", %s)", + fieldName, genericTypeSimpleName, metadata.isStrongReference(field)); break; case INTEGER_LIST: diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java index fb00a17894..4542560645 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java @@ -865,8 +865,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/NullTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java index bef81c5e86..82d6978e65 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java @@ -1717,7 +1717,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 d609d7fc8e..56e6e30416 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..d7cda17a83 --- /dev/null +++ b/realm/realm-library/src/androidTest/java/io/realm/entities/RelationshipParent.java @@ -0,0 +1,35 @@ +/* + * 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.Relationship; +import io.realm.annotations.RelationshipType; + +public class RelationshipParent extends RealmObject { + + @Relationship(RelationshipType.STRONG) + public RelationshipChild strongObjectRef; + + public RelationshipChild weakObjectRef; + + @Relationship(RelationshipType.STRONG) + 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..102c6656a4 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 @@ -77,7 +77,8 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_Property_nativeCreatePersistedLin 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/object-store b/realm/realm-library/src/main/cpp/object-store index 8517ee7f43..5616f811d8 160000 --- a/realm/realm-library/src/main/cpp/object-store +++ b/realm/realm-library/src/main/cpp/object-store @@ -1 +1 @@ -Subproject commit 8517ee7f4378fe0f54945b3e4973766ff65e455d +Subproject commit 5616f811d8a46aac01161140ab808b0c499e0de3 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 dc23ee4f0f..cae0213550 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 @@ -19,6 +19,7 @@ import javax.annotation.Nullable; import io.realm.RealmFieldType; +import io.realm.annotations.Relationship; /** * Immutable Java wrapper for Object Store ObjectSchema. @@ -90,9 +91,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); From 7c4e72c6ff6e1be5b818724559c1ea236c664dfc Mon Sep 17 00:00:00 2001 From: Christian Melchior Date: Fri, 12 Jan 2018 12:18:48 +0100 Subject: [PATCH 3/5] Use only annotation if relationship is strong --- .../io/realm/annotations/Relationship.java | 57 ------------ .../realm/annotations/RelationshipType.java | 73 --------------- .../realm/annotations/StrongRelationship.java | 90 +++++++++++++++++++ .../io/realm/processor/ClassMetaData.java | 11 +-- .../io/realm/entities/RelationshipParent.java | 7 +- 5 files changed, 96 insertions(+), 142 deletions(-) delete mode 100644 realm-annotations/src/main/java/io/realm/annotations/Relationship.java delete mode 100644 realm-annotations/src/main/java/io/realm/annotations/RelationshipType.java create mode 100644 realm-annotations/src/main/java/io/realm/annotations/StrongRelationship.java diff --git a/realm-annotations/src/main/java/io/realm/annotations/Relationship.java b/realm-annotations/src/main/java/io/realm/annotations/Relationship.java deleted file mode 100644 index 27d98cbadc..0000000000 --- a/realm-annotations/src/main/java/io/realm/annotations/Relationship.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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 objects through either a object or list - * reference. See {@link RelationshipType} for a detailed description of the semantics of setting this. - *

- * This annotation can only be applied to fields that reference either an object or a RealmList with - * model classes: - * {@code - * public class Person extends RealmObject { - * - * public String name; - * - * \@Relationship(RelationshipType.STRONG) - * public ContactInfo contactInfo; - * - * \@Relationship(RelationshipType.WEAK) - * public RealmList dogs = new RealmList<>(); - * } - * } - * - * In all other cases the annotation processor will throw an error. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -@Inherited -public @interface Relationship { - - /** - * Set the type of the relationship. See {@link RelationshipType} for more information about the - * semantics. - */ - RelationshipType value() default RelationshipType.WEAK; -} \ No newline at end of file diff --git a/realm-annotations/src/main/java/io/realm/annotations/RelationshipType.java b/realm-annotations/src/main/java/io/realm/annotations/RelationshipType.java deleted file mode 100644 index a775bf4c91..0000000000 --- a/realm-annotations/src/main/java/io/realm/annotations/RelationshipType.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.annotations; - -/** - * Enum describing what kind of relationship exists between two Realm model classes A and B. A - * relationship can either be {@link #WEAK} or {@link #STRONG}. - * - * 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. - */ -public enum RelationshipType { - /** - * Indicates that the relationship between object A and B is strong. This means that B - * will be deleted automatically 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 object is only deleted automatically when the last strong 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 )}. - *
  • - *
- */ - STRONG, - - /** - * Indicates that the relationship between object A and B is weak. This means that A and B - * can exist independently regardless of what happens to the other. - *

- * This is the default relationship type between objects. - *

- * Fields marked with {@link LinkingObjects} is always considered to have a weak relationship. - *

- */ - WEAK, -} 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 e12e5e92bc..b7fcac2f6d 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 @@ -44,9 +44,8 @@ import io.realm.annotations.Index; import io.realm.annotations.LinkingObjects; import io.realm.annotations.PrimaryKey; -import io.realm.annotations.Relationship; -import io.realm.annotations.RelationshipType; import io.realm.annotations.Required; +import io.realm.annotations.StrongRelationship; /** @@ -494,16 +493,12 @@ private boolean categorizeField(Element element) { } // Check that @RealmField is used on the correct fields. - if (field.getAnnotation(Relationship.class) != null) { + 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; } - - RelationshipType relationship = field.getAnnotation(Relationship.class).value(); - if (relationship == RelationshipType.STRONG) { - strongReferences.add(field); - } + strongReferences.add(field); } if (field.getAnnotation(PrimaryKey.class) != null) { 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 index d7cda17a83..7ce477a5d8 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/entities/RelationshipParent.java +++ b/realm/realm-library/src/androidTest/java/io/realm/entities/RelationshipParent.java @@ -17,17 +17,16 @@ import io.realm.RealmList; import io.realm.RealmObject; -import io.realm.annotations.Relationship; -import io.realm.annotations.RelationshipType; +import io.realm.annotations.StrongRelationship; public class RelationshipParent extends RealmObject { - @Relationship(RelationshipType.STRONG) + @StrongRelationship public RelationshipChild strongObjectRef; public RelationshipChild weakObjectRef; - @Relationship(RelationshipType.STRONG) + @StrongRelationship public RealmList strongListRef = new RealmList<>(); public RealmList weakListRef = new RealmList<>(); From 43d9da5351dd9f9cf87e8078c623cea5523cabf2 Mon Sep 17 00:00:00 2001 From: Christian Melchior Date: Fri, 12 Jan 2018 12:19:31 +0100 Subject: [PATCH 4/5] Cleanup --- .../src/main/java/io/realm/internal/OsObjectSchemaInfo.java | 1 - 1 file changed, 1 deletion(-) 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 cae0213550..77f7574848 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 @@ -19,7 +19,6 @@ import javax.annotation.Nullable; import io.realm.RealmFieldType; -import io.realm.annotations.Relationship; /** * Immutable Java wrapper for Object Store ObjectSchema. From cca1ad34f78d58d4d174979381121a3d88b9f244 Mon Sep 17 00:00:00 2001 From: Christian Melchior Date: Fri, 12 Jan 2018 12:51:31 +0100 Subject: [PATCH 5/5] Add missing boolean --- .../realm-library/src/main/cpp/io_realm_internal_Property.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 102c6656a4..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,7 +70,8 @@ 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 {