88 */
99package com .parse ;
1010
11+ import java .lang .ref .WeakReference ;
1112import java .util .Collections ;
1213import java .util .HashSet ;
1314import java .util .Set ;
@@ -24,7 +25,13 @@ public class ParseRelation<T extends ParseObject> {
2425 private final Object mutex = new Object ();
2526
2627 // The owning object of this ParseRelation.
27- private ParseObject parent ;
28+ private WeakReference <ParseObject > parent ;
29+
30+ // The object Id of the parent.
31+ private String parentObjectId ;
32+
33+ // The classname of the parent to retrieve the parent ParseObject in case the parent is GC'ed.
34+ private String parentClassName ;
2835
2936 // The key of the relation in the parent object.
3037 private String key ;
@@ -36,13 +43,17 @@ public class ParseRelation<T extends ParseObject> {
3643 private Set <ParseObject > knownObjects = new HashSet <>();
3744
3845 /* package */ ParseRelation (ParseObject parent , String key ) {
39- this .parent = parent ;
46+ this .parent = new WeakReference <>(parent );
47+ this .parentObjectId = parent .getObjectId ();
48+ this .parentClassName = parent .getClassName ();
4049 this .key = key ;
4150 this .targetClass = null ;
4251 }
4352
4453 /* package */ ParseRelation (String targetClass ) {
4554 this .parent = null ;
55+ this .parentObjectId = null ;
56+ this .parentClassName = null ;
4657 this .key = null ;
4758 this .targetClass = targetClass ;
4859 }
@@ -52,6 +63,8 @@ public class ParseRelation<T extends ParseObject> {
5263 */
5364 /* package */ ParseRelation (JSONObject jsonObject , ParseDecoder decoder ) {
5465 this .parent = null ;
66+ this .parentObjectId = null ;
67+ this .parentClassName = null ;
5568 this .key = null ;
5669 this .targetClass = jsonObject .optString ("className" , null );
5770 JSONArray objectsArray = jsonObject .optJSONArray ("objects" );
@@ -65,12 +78,14 @@ public class ParseRelation<T extends ParseObject> {
6578 /* package */ void ensureParentAndKey (ParseObject someParent , String someKey ) {
6679 synchronized (mutex ) {
6780 if (parent == null ) {
68- parent = someParent ;
81+ parent = new WeakReference <>(someParent );
82+ parentObjectId = someParent .getObjectId ();
83+ parentClassName = someParent .getClassName ();
6984 }
7085 if (key == null ) {
7186 key = someKey ;
7287 }
73- if (parent != someParent ) {
88+ if (parent . get () != someParent ) {
7489 throw new IllegalStateException (
7590 "Internal error. One ParseRelation retrieved from two different ParseObjects." );
7691 }
@@ -92,7 +107,7 @@ public void add(T object) {
92107 ParseRelationOperation <T > operation =
93108 new ParseRelationOperation <>(Collections .singleton (object ), null );
94109 targetClass = operation .getTargetClass ();
95- parent .performOperation (key , operation );
110+ getParent () .performOperation (key , operation );
96111
97112 knownObjects .add (object );
98113 }
@@ -109,7 +124,7 @@ public void remove(T object) {
109124 ParseRelationOperation <T > operation =
110125 new ParseRelationOperation <>(null , Collections .singleton (object ));
111126 targetClass = operation .getTargetClass ();
112- parent .performOperation (key , operation );
127+ getParent () .performOperation (key , operation );
113128
114129 knownObjects .remove (object );
115130 }
@@ -124,12 +139,12 @@ public ParseQuery<T> getQuery() {
124139 synchronized (mutex ) {
125140 ParseQuery .State .Builder <T > builder ;
126141 if (targetClass == null ) {
127- builder = new ParseQuery .State .Builder <T >(parent . getClassName () )
142+ builder = new ParseQuery .State .Builder <T >(parentClassName )
128143 .redirectClassNameForKey (key );
129144 } else {
130145 builder = new ParseQuery .State .Builder <>(targetClass );
131146 }
132- builder .whereRelatedTo (parent , key );
147+ builder .whereRelatedTo (getParent () , key );
133148 return new ParseQuery <>(builder );
134149 }
135150 }
@@ -193,7 +208,13 @@ public ParseQuery<T> getQuery() {
193208 }
194209
195210 /* package for tests */ ParseObject getParent () {
196- return parent ;
211+ if (parent == null ){
212+ return null ;
213+ }
214+ if (parent .get () == null ){
215+ return ParseObject .createWithoutData (parentClassName , parentObjectId );
216+ }
217+ return parent .get ();
197218 }
198219
199220 /* package for tests */ String getKey () {
0 commit comments