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

JaVers runtime error - diff for Set of ValueObjects is not supported #191

Closed
lathy88 opened this issue Aug 20, 2015 · 17 comments
Closed

JaVers runtime error - diff for Set of ValueObjects is not supported #191

lathy88 opened this issue Aug 20, 2015 · 17 comments
Assignees
Labels

Comments

@lathy88
Copy link

lathy88 commented Aug 20, 2015

Recently i got this error,

can not handle managed/back reference 'defaultreference' in jackson for composite key
I googled alot but found the below option to use,

JsonManagedReference and JsonBackReference
Reference-> http://wiki.fasterxml.com/JacksonFeatureBiDirReferences

But my situation is,

Class Parent{
private int id;
@JsonManagedReference
Set childSet;
}

Class Child{
private ChildId childId;
private String name;
}

Class ChildId{
private int childKey;
@JsonBackReference
private Parent parent;
}
As you see, in the child class it has a composite key. I can not change this since it has relationship with DB.

Can anybody help me with this issue?

Note:
I'm using Jackson 2.4.3
I'm using Javers 1.2.9 for Object comparison

Update:

I removed all the JsonManaged and JsonBackReference annotations and added only JsonIgonre in Child as below,
Class ChildId{
private int childKey;
@JsonIgnore
private Parent parent;
}

After doing this I got the below error,

11:39:59,712 ERROR SetChangeAppender:46 - could not diff Field Set Child1; //declared in: Parent, JaVers runtime error - diff for Set of ValueObjects is not supported

@bartoszwalacik
Copy link
Member

well, first, JaVers doesn't know anything about Jackson and its annotations

The error you see - 'diff for Set of ValueObjects is not supported' means that you cannot manage Sets of ValueObject in Javers.
Try to map your entities (Parent and Child) as Entities.

@lathy88
Copy link
Author

lathy88 commented Aug 24, 2015

Hi Barto,
Thank you for your reply.
Could you please tell me what you mean by map your entities (Parent and Child) as Entities?

@bartoszwalacik
Copy link
Member

@bartoszwalacik
Copy link
Member

@lathy88, reopen this ticket if our documentation won't help you

@arnzel
Copy link

arnzel commented Jan 28, 2016

Why is diff for sets in value objects not supported ?

@andreasBerre
Copy link

was just wondering the same thing, entities with sets of value objects should be a pretty common use-case?

@bartoszwalacik
Copy link
Member

The reason why JaVers doesn't support diff for Sets of ValueObjects is simple, we have no good idea how to do this :)

Imagine that you have two sets with ValueObjects.
By definition, ValueObjects dont have identifiers, how would you choose pairs to compare from left and right set? If you can suggest some good algorithm, we will do it.

@andreasBerre
Copy link

heh, I see your point, alterations would per definition be impossible to track. Best you could do is consider the set itself a value object, and detect if it had changed (objects added/removed), would be useful in my use-case at least. Maybe as a SetChange?

@bartoszwalacik
Copy link
Member

true, new algorithm could detect only added/removed object.
Objects could be compared using kind of propertyEquals(o1,o2) method.
Of course, we dont wont n2 complexity, so first, we should calculate digest for each object (based on all its properties).

Digest heuristic is not obvious, we could try simply stringify and join all properties. But many Classes dont have good value-based toString()...

@andreasBerre
Copy link

Hm, I'd have thought you might just use object.equals, and delegate all the problems to the individual developers? We won't be able to track individual property changes, but since a changed value object is per definition a new value object that sort of makes sense?

@andreasBerre
Copy link

or that might be a bad idea, since the rest of Javers doesn't require you to implement equals... so stringify and join might be better...

@bartoszwalacik
Copy link
Member

Thats because many devs dont provide good equals() so we should not rely on it. We have ReflectionUtil.reflectiveToString() but it doesnt suit perfectly for this issue. Still, besides equals(), we need digest function (we dont want to fall into n2 complexity problem).
Fortunately, we can use shaDigest from MethodFactory...

@andreasBerre
Copy link

Will you consider opening a issue for this?

@bartoszwalacik
Copy link
Member

new Issue can be created easily, the problem is we don't have manpower to develop this ...

@bartoszwalacik bartoszwalacik self-assigned this Mar 2, 2016
bartoszwalacik added a commit that referenced this issue Mar 10, 2016
failing tests and OwnerContext refactoring
bartoszwalacik added a commit that referenced this issue Mar 14, 2016
@bartoszwalacik
Copy link
Member

fixed in release 1.6.0

@ndsurendra
Copy link
Contributor

Hi @bartoszwalacik, could you please give a gist of the changes you made in this fix?
Is this relying on the equals method? I implemented equals method for my value object, but it still seems to treat them as different objects.
If it is not using the equals method, can we do that? Because, Java Set itself relies on the equals method to make sure no duplicates exist in the set.

Please suggest.

Here is my test case:
Javers javers = JaversBuilder.javers().build();
SetConMap oldMap = new SetConMap();
Set oldSysCons = new HashSet<>();
oldMap.setSysCons(oldSysCons);
oldSysCons.add(new Contact().sysCode("AL").localId("123").goldenId("ABC"));
oldSysCons.add(new Contact().sysCode("AL").localId("456").goldenId("ABC"));

    SetConMap newMap = new SetConMap();
    Set<Contact> newSysCons = new HashSet<>();
    newMap.setSysCons(newSysCons);
    newSysCons.add(new Contact().sysCode("AL").localId("123").goldenId("DEF"));
    newSysCons.add(new Contact().sysCode("AL").localId("456").goldenId("DEF"));
    newSysCons.add(new Contact().sysCode("AL").localId("789").goldenId("DEF"));

    Diff diff = javers.compare(oldMap, newMap);
    System.out.println(diff);

I'm using sysCode and localId as a combined identifier for the object, not including the goldenId.
But the diff (output below the class) is not recognizing that equal objects and showing the diff as all the objects in the old set as removed and the objects in the new se as added, which doesn't seem to add any value.

private static class Contact {
    private String sysCode;
    private String localId;
    private String goldenId;

//getters, setters.
@OverRide
public int hashCode() {
return super.hashCode();
}

    @Override
    public boolean equals(Object obj) {
        return obj != null && (obj instanceof Contact) && Objects.equals(sysCode, ((Contact) obj).getSysCode())
            && Objects.equals(localId, ((Contact) obj).getLocalId());
    }

}

Diff:

  • new object: org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/c76fadcd55d4dbf6d8cbe49310b1ab26
  • new object: org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/96b23b34a0f42a5105491350db5c46f1
  • new object: org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/a9c7f46bbe5f0e46b5751f3f5c5d8542
  • object removed: org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/a53e4ba1b22c4f290a80daf40adf5d81
  • object removed: org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/782edf187b8add9bab004ca06f7b6c7c
  • changes on org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/ :
    • 'sysCons' collection changes :
      . 'org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/782edf187b8add9bab004ca06f7b6c7c' removed
      . 'org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/a53e4ba1b22c4f290a80daf40adf5d81' removed
      . 'org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/a9c7f46bbe5f0e46b5751f3f5c5d8542' added
      . 'org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/c76fadcd55d4dbf6d8cbe49310b1ab26' added
      . 'org.ishafoundation.cdi.web.rest.GoldenContactResource$SetConMap/#sysCons/96b23b34a0f42a5105491350db5c46f1' added

@bartoszwalacik
Copy link
Member

@ndsurendra please do not comment on closed issues, if you have a question, ask at https://stackoverflow.com/questions/tagged/javers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants