Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UnsupportedOperationException committing empty ValueObject when previous version was not empty #815

Closed
crombach opened this Issue Mar 26, 2019 · 2 comments

Comments

Projects
None yet
2 participants
@crombach
Copy link
Contributor

crombach commented Mar 26, 2019

org.javers.common.collections.Sets throws an UnsupportedOperationException when xor(Set<E> first, Set<E> second) is called and the first argument is empty (or null) and the second argument is not null and not empty.

This exception can be reproduced using the following simple test case:

import org.javers.core.Javers;
import org.javers.core.JaversBuilder;
import org.javers.core.metamodel.annotation.Entity;
import org.javers.core.metamodel.annotation.Id;
import org.javers.core.metamodel.annotation.ValueObject;
import org.javers.repository.inmemory.InMemoryRepository;

public class TestSetsUnsupportedOperation {
    public static void main(String[] args) {
        InMemoryRepository repo = new InMemoryRepository();
        Javers javers = JaversBuilder.javers().registerJaversRepository(repo).build();

        // Create a RangeHolder with a Range that has some values.
        RangeHolder versionOne = new RangeHolder();
        versionOne.setId("id");
        Range populatedRange = new Range();
        populatedRange.setMin(0);
        populatedRange.setMax(100);
        versionOne.setRange(populatedRange);

        // Commit the first version.
        javers.commit("tester", versionOne);

        // Update the RangeHolder with an empty Range (all fields are null).
        RangeHolder versionTwo = new RangeHolder();
        versionTwo.setId("id");
        Range emptyRange = new Range();
        versionTwo.setRange(emptyRange);

        // Commit the second version. Throws an UnsupportedOperationException.
        javers.commit("tester", versionTwo);
    }
}

@Entity
class RangeHolder {
    @Id
    private String id;
    private Range range;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Range getRange() {
        return range;
    }

    public void setRange(Range range) {
        this.range = range;
    }
}

@ValueObject
class Range {
    private Integer min;
    private Integer max;

    public Integer getMin() {
        return min;
    }

    public void setMin(Integer min) {
        this.min = min;
    }

    public Integer getMax() {
        return max;
    }

    public void setMax(Integer max) {
        this.max = max;
    }
}

Suggest changing org.javers.common.collections.Sets#xor(Set<E> first, Set<E> second) to wrap the results of the first call to the difference(Set<E> first, Set<E> second) method with a new HashSet, like this:

public static <E> Set<E> xor(Set<E> first, Set<E> second) {
    Set<E> xor = new HashSet<>(difference(first, second));
    xor.addAll(difference(second, first));
    return xor;
}

Making this change causes the test above to pass without an exception.

@bartoszwalacik

This comment has been minimized.

Copy link
Member

bartoszwalacik commented Mar 26, 2019

Hi, thanks for reporting, could you please create a PR with this test case and a fix?
Please put the test case here: https://github.com/javers/javers/tree/master/javers-core/src/test/groovy/org/javers/core/cases

@bartoszwalacik

This comment has been minimized.

Copy link
Member

bartoszwalacik commented Mar 29, 2019

Thanks @crombach , fix is released in 5.3.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.