I was wondering if there is a way to mark some properties as immutable
value properties, that is, properties that holds values that can't be
modified after creation and, thus, should not be deep copied. An example
unit test below. Basically, there is a SomeId class, which is immutable.
SomeEntity class have a property of SomeId type. Mapping SomeEntity to
another SomeEntity does not copy the id property as I expected it to. It
would be nice to be able to mark the id property of SomeEntity or the
SomeId class as immutable (via annotation or MergingContext) and have java
merger just copy such properties (the same way it does it for String class
and other built in immutables).
I tried to achieve it using PropertyConverter with no success. My current
workaround is to @Skip the id property and to copy it manually after the
mapping, which is kind of ugly.
public class MergerTest {
/**
* Some immutable class that should not be deep copied
*/
public static class SomeId {
private long innerId;
public SomeId(int innerId) {
this.innerId = innerId;
}
/**
* There should not be public constructor with no parameters because this is an immutable class,
* but merger fails with ObjectCreationException otherwise
*/
public SomeId() {
}
/**
* Compares by inner id.
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SomeId someId = (SomeId) o;
if (innerId != someId.innerId) return false;
return true;
}
@Override
public int hashCode() {
return (int) (innerId ^ (innerId >>> 32));
}
}
/**
* Bean class with an immutable property
*/
public static class SomeEntity {
private SomeId id;
public SomeId getId() {
return id;
}
public void setId(SomeId id) {
this.id = id;
}
}
@Test
public void testImmutableMapping() throws Exception {
IMergingContext mergingContext = new MergingContext();
SomeEntity a = new SomeEntity();
a.setId(new SomeId(5));
SomeEntity result = mergingContext.map(a, SomeEntity.class);
assertEquals(result.getId(), a.getId());
}
}
Last edit: Servy 2014-07-07
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I was wondering if there is a way to mark some properties as immutable
value properties, that is, properties that holds values that can't be
modified after creation and, thus, should not be deep copied. An example
unit test below. Basically, there is a SomeId class, which is immutable.
SomeEntity class have a property of SomeId type. Mapping SomeEntity to
another SomeEntity does not copy the id property as I expected it to. It
would be nice to be able to mark the id property of SomeEntity or the
SomeId class as immutable (via annotation or MergingContext) and have java
merger just copy such properties (the same way it does it for String class
and other built in immutables).
I tried to achieve it using PropertyConverter with no success. My current
workaround is to @Skip the id property and to copy it manually after the
mapping, which is kind of ugly.
Last edit: Servy 2014-07-07
To make it work as you expected, you should declare SomeId.class as value type in MergingContext. Like this:
mergingContext.setValueTypes(Arrays.asList(SomeId.class));
See javadoc of method 'setValueTypes' for details.
Then costructor with no arguments in SomeId could aslo be removed.