Skip to content

Commit 288d3e0

Browse files
committed
ToMany: fix removal of non-persisted entities for stand-alone relations (removeStandaloneRelations removes non-persisted entities first)
1 parent 417c2df commit 288d3e0

File tree

2 files changed

+53
-17
lines changed

2 files changed

+53
-17
lines changed

objectbox-java/src/main/java/io/objectbox/relation/ToMany.java

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ public void internalApplyToDb(Cursor sourceCursor, Cursor<TARGET> targetCursor)
727727
TARGET[] toRemoveFromDb;
728728
TARGET[] toPut;
729729
TARGET[] addedStandalone = null;
730-
TARGET[] removedStandalone = null;
730+
List<TARGET> removedStandalone = null;
731731

732732
boolean isStandaloneRelation = relationInfo.relationId != 0;
733733
IdGetter<TARGET> targetIdGetter = relationInfo.targetInfo.getIdGetter();
@@ -746,7 +746,7 @@ public void internalApplyToDb(Cursor sourceCursor, Cursor<TARGET> targetCursor)
746746
entitiesAdded.clear();
747747
}
748748
if (!entitiesRemoved.isEmpty()) {
749-
removedStandalone = (TARGET[]) entitiesRemoved.keySet().toArray();
749+
removedStandalone = new ArrayList<>(entitiesRemoved.keySet());
750750
entitiesRemoved.clear();
751751
}
752752
}
@@ -777,26 +777,51 @@ public void internalApplyToDb(Cursor sourceCursor, Cursor<TARGET> targetCursor)
777777
throw new IllegalStateException("Source entity has no ID (should have been put before)");
778778
}
779779

780-
checkModifyStandaloneRelation(sourceCursor, entityId, removedStandalone, targetIdGetter, true);
781-
checkModifyStandaloneRelation(sourceCursor, entityId, addedStandalone, targetIdGetter, false);
780+
if (removedStandalone != null) {
781+
removeStandaloneRelations(sourceCursor, entityId, removedStandalone, targetIdGetter);
782+
}
783+
if (addedStandalone != null) {
784+
addStandaloneRelations(sourceCursor, entityId, addedStandalone, targetIdGetter, false);
785+
}
782786
}
783787
}
784788

785-
private void checkModifyStandaloneRelation(Cursor cursor, long sourceEntityId, @Nullable TARGET[] targets,
786-
IdGetter<TARGET> targetIdGetter, boolean remove) {
787-
if (targets != null) {
788-
int length = targets.length;
789-
long[] targetIds = new long[length];
790-
for (int i = 0; i < length; i++) {
791-
long targetId = targetIdGetter.getId(targets[i]);
792-
if (targetId == 0) {
793-
// Paranoia
794-
throw new IllegalStateException("Target entity has no ID (should have been put before)");
795-
}
796-
targetIds[i] = targetId;
789+
/**
790+
* The list of removed entities may contain non-persisted entities, which will be ignored (removed from the list).
791+
*/
792+
private void removeStandaloneRelations(Cursor cursor, long sourceEntityId, List<TARGET> removed,
793+
IdGetter<TARGET> targetIdGetter) {
794+
Iterator<TARGET> iterator = removed.iterator();
795+
while (iterator.hasNext()) {
796+
if (targetIdGetter.getId(iterator.next()) == 0) {
797+
iterator.remove();
798+
}
799+
}
800+
801+
int size = removed.size();
802+
if (size > 0) {
803+
long[] targetIds = new long[size];
804+
for (int i = 0; i < size; i++) {
805+
targetIds[i] = targetIdGetter.getId(removed.get(i));
806+
}
807+
cursor.modifyRelations(relationInfo.relationId, sourceEntityId, targetIds, true);
808+
}
809+
}
810+
811+
/** The target array may not contain non-persisted entities. */
812+
private void addStandaloneRelations(Cursor cursor, long sourceEntityId, @Nullable TARGET[] added,
813+
IdGetter<TARGET> targetIdGetter, boolean remove) {
814+
int length = added.length;
815+
long[] targetIds = new long[length];
816+
for (int i = 0; i < length; i++) {
817+
long targetId = targetIdGetter.getId(added[i]);
818+
if (targetId == 0) {
819+
// Paranoia
820+
throw new IllegalStateException("Target entity has no ID (should have been put before)");
797821
}
798-
cursor.modifyRelations(relationInfo.relationId, sourceEntityId, targetIds, remove);
822+
targetIds[i] = targetId;
799823
}
824+
cursor.modifyRelations(relationInfo.relationId, sourceEntityId, targetIds, remove);
800825
}
801826

802827
/** For tests */

tests/objectbox-java-test/src/main/java/io/objectbox/relation/ToManyStandaloneTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,17 @@ public void testRemove() {
219219
assertOrder2And4Removed(count, customer, toMany);
220220
}
221221

222+
@Test
223+
public void testAddRemove_notPersisted() {
224+
Customer customer = putCustomer();
225+
ToMany<Order> toMany = customer.ordersStandalone;
226+
Order order = new Order();
227+
toMany.add(order);
228+
toMany.remove(order);
229+
customerBox.put(customer);
230+
assertEquals(0, orderBox.count());
231+
}
232+
222233
@Test
223234
public void testRemoveAll() {
224235
int count = 5;

0 commit comments

Comments
 (0)