Comparison of Set of Set non-deterministic
See original GitHub issueI have a data structure which contains a set of set. When comparing with javers I sometimes get a diff, sometimes not. The test data is static so I would expect an identical output.
Steps To Reproduce
When I run this class containing the two identical objects a1 and a2:
import lombok.Builder;
import lombok.Data;
import org.javers.core.Javers;
import org.javers.core.JaversBuilder;
import java.util.Set;
public class MyTest {
@Data
@Builder
public static class A {
private Set<B> bs;
}
@Data
@Builder
public static class B {
private Set<C> cs;
}
@Data
@Builder
public static class C {
private String foo;
}
public static void main(String[] args) {
Javers javers = JaversBuilder.javers().build();
A a1 = A.builder().bs(Set.of(
B.builder()
.cs(
Set.of(
C.builder().foo("a").build(),
C.builder().foo("b").build()
)).build())).build();
A a2 = A.builder().bs(Set.of(
B.builder()
.cs(
Set.of(
C.builder().foo("a").build(),
C.builder().foo("b").build()
)).build())).build();
for (int i = 0; i < 10; i++) {
var diff = javers.compare(a1, a2);
if (diff.hasChanges()) {
System.out.printf("\n===== Diff at round %d ======\n", i);
System.out.println(diff);
}
}
}
}
… I receive the following output:
20:51:47.647 [main] DEBUG org.javers.core.JaversBuilder - starting up JaVers ...
20:51:47.724 [main] INFO org.javers.core.JaversBuilder - mappingStyle: FIELD
20:51:47.732 [main] INFO org.javers.core.JaversBuilder - loading JodaAddOns ...
20:51:47.786 [main] INFO org.javers.core.JaversBuilder - loading GuavaAddOns ...
20:51:47.841 [main] DEBUG org.javers.TypeMapper - javersType of 'LocalDateTime' mapped explicitly to ValueType
20:51:47.841 [main] DEBUG org.javers.TypeMapper - javersType of 'LocalDate' mapped explicitly to ValueType
20:51:47.842 [main] INFO org.javers.core.JaversBuilder - using fake InMemoryRepository, register actual Repository implementation via JaversBuilder.registerJaversRepository()
20:51:47.870 [main] INFO org.javers.core.JaversBuilder - JaVers instance started in 225 ms
20:51:47.890 [main] DEBUG org.javers.TypeMapper - javersType for 'class MyTest$A' defaulted to ValueObjectType
20:51:47.903 [main] DEBUG org.javers.TypeMapper - javersType for 'java.util.Set<MyTest$B>' spawned as SetType from prototype SetType{ baseType: 'interface java.util.Set' }
20:51:47.905 [main] DEBUG org.javers.TypeMapper - javersType for 'class MyTest$B' defaulted to ValueObjectType
20:51:47.907 [main] DEBUG org.javers.TypeMapper - javersType for 'java.util.Set<MyTest$C>' spawned as SetType from prototype SetType{ baseType: 'interface java.util.Set' }
20:51:47.908 [main] DEBUG org.javers.TypeMapper - javersType for 'class MyTest$C' defaulted to ValueObjectType
20:51:47.909 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.938 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.949 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.951 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
===== Diff at round 1 ======
Diff:
* changes on MyTest$A/ :
- 'bs' collection changes :
. 'MyTest$A/#bs/9f83e3c27e7b610b0a0317a0f008f195' removed
· 'MyTest$A/#bs/f80bbd079e4ee10592dc0f6f850bacb7' added
- 'bs/9f83e3c27e7b610b0a0317a0f008f195.cs' collection changes :
. 'MyTest$A/#bs/{hashPlaceholder}/cs/74a563c16582541b5f7d011fe538602a' removed
. 'MyTest$A/#bs/{hashPlaceholder}/cs/7f2b9fa7d40fb28ae704fb57f5db54ee' removed
- 'bs/f80bbd079e4ee10592dc0f6f850bacb7.cs' collection changes :
· 'MyTest$A/#bs/{hashPlaceholder}/cs/74a563c16582541b5f7d011fe538602a' added
· 'MyTest$A/#bs/{hashPlaceholder}/cs/7f2b9fa7d40fb28ae704fb57f5db54ee' added
20:51:47.971 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.972 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
===== Diff at round 2 ======
Diff:
* changes on MyTest$A/ :
- 'bs' collection changes :
. 'MyTest$A/#bs/9f83e3c27e7b610b0a0317a0f008f195' removed
· 'MyTest$A/#bs/f80bbd079e4ee10592dc0f6f850bacb7' added
- 'bs/9f83e3c27e7b610b0a0317a0f008f195.cs' collection changes :
. 'MyTest$A/#bs/{hashPlaceholder}/cs/74a563c16582541b5f7d011fe538602a' removed
. 'MyTest$A/#bs/{hashPlaceholder}/cs/7f2b9fa7d40fb28ae704fb57f5db54ee' removed
- 'bs/f80bbd079e4ee10592dc0f6f850bacb7.cs' collection changes :
· 'MyTest$A/#bs/{hashPlaceholder}/cs/74a563c16582541b5f7d011fe538602a' added
· 'MyTest$A/#bs/{hashPlaceholder}/cs/7f2b9fa7d40fb28ae704fb57f5db54ee' added
20:51:47.978 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.980 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.982 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.983 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.985 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.987 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.989 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.991 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
===== Diff at round 6 ======
Diff:
* changes on MyTest$A/ :
- 'bs' collection changes :
. 'MyTest$A/#bs/9f83e3c27e7b610b0a0317a0f008f195' removed
· 'MyTest$A/#bs/f80bbd079e4ee10592dc0f6f850bacb7' added
- 'bs/9f83e3c27e7b610b0a0317a0f008f195.cs' collection changes :
. 'MyTest$A/#bs/{hashPlaceholder}/cs/74a563c16582541b5f7d011fe538602a' removed
. 'MyTest$A/#bs/{hashPlaceholder}/cs/7f2b9fa7d40fb28ae704fb57f5db54ee' removed
- 'bs/f80bbd079e4ee10592dc0f6f850bacb7.cs' collection changes :
· 'MyTest$A/#bs/{hashPlaceholder}/cs/74a563c16582541b5f7d011fe538602a' added
· 'MyTest$A/#bs/{hashPlaceholder}/cs/7f2b9fa7d40fb28ae704fb57f5db54ee' added
20:51:47.994 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.996 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.997 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:47.998 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:48.000 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
20:51:48.001 [main] DEBUG org.javers.core.graph.ObjectGraphBuilder - live graph assembled, object nodes: 4, entities: 0, valueObjects: 3
===== Diff at round 9 ======
Diff:
* changes on MyTest$A/ :
- 'bs' collection changes :
. 'MyTest$A/#bs/9f83e3c27e7b610b0a0317a0f008f195' removed
· 'MyTest$A/#bs/f80bbd079e4ee10592dc0f6f850bacb7' added
- 'bs/9f83e3c27e7b610b0a0317a0f008f195.cs' collection changes :
. 'MyTest$A/#bs/{hashPlaceholder}/cs/74a563c16582541b5f7d011fe538602a' removed
. 'MyTest$A/#bs/{hashPlaceholder}/cs/7f2b9fa7d40fb28ae704fb57f5db54ee' removed
- 'bs/f80bbd079e4ee10592dc0f6f850bacb7.cs' collection changes :
· 'MyTest$A/#bs/{hashPlaceholder}/cs/74a563c16582541b5f7d011fe538602a' added
· 'MyTest$A/#bs/{hashPlaceholder}/cs/7f2b9fa7d40fb28ae704fb57f5db54ee' added
Process finished with exit code 0
Interestingly enough the diff appears (at least on my machine) always on the same rounds.
When the inner set (Set of C) only contains one entry, the diff works as expected - there is no difference 😉
What do I miss?
Javers’ Version 6.42
Additional context
- I am a JaVers newbie
- I have tried the three different list comparison algorithms without a change of the output above.
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (4 by maintainers)
Top Results From Across the Web
Difference between Deterministic and Non ... - GeeksforGeeks
In a deterministic algorithm, for a given particular input, the computer will always produce the same output going through the same states ...
Read more >Deterministic and Nondeterministic Functions - SQL Server
Nondeterministic functions may return different results each time they're called with a specific set of input values even if the database state ...
Read more >Matching two sets when you cannot do within-set comparisons
Suppose you have two lists, A and B , each with length n. The elements of A cannot be compared with other elements...
Read more >Nondeterministic collations - PostgreSQL Notes
Starting with version 12, the new “deterministic” property can be set to false at CREATE COLLATION time to request that string comparisons ......
Read more >Is set deterministic? [duplicate] - python - Stack Overflow
Sure, one can sort the outcome to enforce deterministic behavior, but you can get such idea once you observe you have non-deterministic code...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

Hi, I’ve tried to fumble together a failing test case: https://github.com/javers/javers/pull/1158
Please feel free to improve my copy + paste groovy code 😉
it should, just try the new version 😃