atos1990 / orika

Automatically exported from code.google.com/p/orika
0 stars 0 forks source link

Add customization of collection mapping. #25

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I map Dto to hibernate entity. Orika recursively rebuild all associated 
collection, therefore every entity which has collection became dirty and 
hibernate updates DB. I need to registrate base smart collection merger. 
Such as:
Collection<BaseDto> dstDtos merge( Collection<BaseDto> srcDtos , 
Collection<BaseDto> dstEntities, Mapper mapper  ){
 //change existing collection instead of rebuild
}
more details see in attach

Original issue reported on code.google.com by dkhomya...@gmail.com on 8 Jun 2012 at 9:47

Attachments:

GoogleCodeExporter commented 9 years ago
The related discuss is
https://groups.google.com/group/orika-discuss/browse_thread/thread/7720d8726a432
ef6

Original comment by dkhomya...@gmail.com on 9 Jun 2012 at 7:00

GoogleCodeExporter commented 9 years ago

Original comment by elaat...@gmail.com on 9 Jun 2012 at 5:32

GoogleCodeExporter commented 9 years ago

Original comment by elaat...@gmail.com on 9 Jun 2012 at 5:34

GoogleCodeExporter commented 9 years ago
by "merge", do you mean that if a collection A is to be mapped into another B, 
you don't want existing items in B removed if there's no corresponding value in 
A?

or is it more that that values in A should be mapped into B, with the end 
result that B should only contain mapped values from A, but items that would be 
unchanged are not replaced?

what I'm trying to figure out is, if Orika avoided creating any new elements 
for a collection and instead modified in place those which already existed, 
(and removed elements which did not have a corresponding value in the source 
collection/array?), would that solve this problem?

Original comment by matt.deb...@gmail.com on 10 Jun 2012 at 5:53

GoogleCodeExporter commented 9 years ago
if Orika avoided creating any new elements for a collection and instead 
modified in place those which already existed, and removed elements which did 
not have a corresponding value in the source collection/array. I'll be happy. 
Yes,  that solve this problem. Merger should tell Orika how to find 
corresponding values in B for values from A. New element should be created if 
merger didn't find corresponding element in the destination collection. For 
circle, B to A to B if A doesn't  be modified then B should not be modified too.

Original comment by dkhomya...@gmail.com on 10 Jun 2012 at 8:16

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
In more common solution, a custom merger must map collection A to B itself, and 
only delegate to map element from A to element from B back to Orika. 
The cause of the problem is that hibernate persistent collection becoming dirty 
for any modifing. For example : 
group.getUsers().remove(user1);
group.getUsers().add(user1); // reverting state of collection
Collection of users is marked as dirty and hibernate generate excess sql update.

Original comment by dkhomya...@gmail.com on 11 Jun 2012 at 9:17

GoogleCodeExporter commented 9 years ago
In the 1.2.0 branch, this capability can now be achieved by explicitly 
registering a custom mapper.
See the attached test case for an example which is very close to the original 
example proposed. This solution is preferable from an API standpoint, because 
it means we can reuse an existing type (CustomMapper), and my thinking is that 
this mechanism could be used to satisfy many other use cases as well.
Please see if the attached example seems acceptable for your use case...

Original comment by matt.deb...@gmail.com on 9 Jul 2012 at 1:57

Attachments:

GoogleCodeExporter commented 9 years ago
It's nice capability, which will resolve all my problem. I look forward to 
release 1.2.*. 
Thanks a lot!

Original comment by dkhomya...@gmail.com on 9 Jul 2012 at 8:02

GoogleCodeExporter commented 9 years ago
This capability is now available in the 1.2.0 branch.

Original comment by matt.deb...@gmail.com on 11 Jul 2012 at 6:24

GoogleCodeExporter commented 9 years ago
I've tested  the 1.2.0 branch. Unfortunally, It doesn't work well. I need 
capability to registrate the merger for Collection<Dto> to Collection<Enrity>. 
This merger has to apply for all subclasses such as:
Collection<ChildDto> to Collection<ChildEnrity>
List<Child2Dto> to Set<ChildEnrity>
List<ChildDto> to List<ChildEnrity> 
and so on
I've added method testMergingWithCustomMapperForChildren in junit test which 
demonstrate my desire.

Original comment by dkhomya...@gmail.com on 21 Aug 2012 at 8:51

Attachments:

GoogleCodeExporter commented 9 years ago
Ok, I've applied another fix in the 1.2.0 branch which should resolve this new 
test case.
Please verify if you get  a chance...

Original comment by matt.deb...@gmail.com on 23 Aug 2012 at 5:24

GoogleCodeExporter commented 9 years ago
Thanks! But, I catch exception if I map Set<ChildDto> to Set<ChildEntity> 
(testMergingWithCustomMapperForChildrenSetToSet in attach). And MergingMapper 
must have   
the signature CustomMapper<Collection<? extends Dto>, Collection<? extends 
Entity>>, because Collection<Dto> isn't assignable from Collection<ChildDto>.

Original comment by dkhomya...@gmail.com on 23 Aug 2012 at 8:37

Attachments:

GoogleCodeExporter commented 9 years ago
Sorry for the late response; try with the most current updates to the branch.
I've made some fixes to the way conrcrete types resolve, including automatic 
registration of some default raw concrete types for Collection, List, Set, Map 
and Map.Entry (which can be overridden as needed, of course)

Original comment by matt.deb...@gmail.com on 28 Aug 2012 at 5:31

GoogleCodeExporter commented 9 years ago
I've  found the problems in api. Class of entity destination is unknown in 
merge. Such, the merger create instance of Entity.class instead of 
ChildEntity.class. Another problem is cast errors for generic collection. I 've 
added assertion in testMergingWithCustomMapperForChildrenSetToSet which 
demonstrate first  problem. And DesiredMergingMapper which should resolve this 
two problems.
Excuse me for slowness.

Original comment by dkhomya...@gmail.com on 10 Sep 2012 at 8:43

Attachments:

GoogleCodeExporter commented 9 years ago
Thanks for the update, and the test case. Always helpful.
I think this may require update to the Mapper interface, since we don't 
currently have any signatures that pass the resolved Type<?> into the mapper 
(although we have it available).
We have a pending fix release 1.2.1, and I can probably look at incorporating 
it after this.

Original comment by matt.deb...@gmail.com on 11 Sep 2012 at 7:22

GoogleCodeExporter commented 9 years ago
A fix has been applied in the current master (1.4.0-SNAPSHOT) which makes the 
resolved source and destination types available on the MappingContext, which 
could be used from your custom mapper.
Please see the attached modifications to the test case which now pass.

Original comment by matt.deb...@gmail.com on 30 Nov 2012 at 1:51

Attachments:

GoogleCodeExporter commented 9 years ago
I've tested trunk. All work fine!  I've found small bug in 
CustomMergerTest:184, line should be  "mapperFacade.map(memberDto, 
memberEntity);" instead of  "mapperFacade.map(memberEntity, memberDto);"

Thanks a lot!

Original comment by dkhomya...@gmail.com on 10 Dec 2012 at 12:42

GoogleCodeExporter commented 9 years ago

Original comment by elaat...@gmail.com on 8 Mar 2013 at 8:59

GoogleCodeExporter commented 9 years ago
Guys, hello!
Thanks for a great project!
Unfortunately,  this issue is not completely resolved. The main idea is that 
special collections that used by hibernate (e.g. 
org.hibernate.collection.internal.PersistentBag and etc) for holding entities 
do not pass the check of the type equality with 
ma.glasnost.orika.metadata.Type.isAssignableFrom(Type<?>) on runtime. And vice 
versa if I register a special custom mapper for PersistentBag to/from 
java.util.Collection<MyEntity> it will never be applied, since there is the 
Collection<MyEntity>  field originally in parent. Please advise any workaround 
for this situation.

Original comment by pavlik.x...@gmail.com on 29 Nov 2013 at 3:26

GoogleCodeExporter commented 9 years ago
Addition to the previous comment. As I have found a moment ago, fix was broken 
between 1.4.1 and 1.4.2 releases. I mean 1.4.1 works for me, but 1.4.2 and 
1.4.3 - not. The unit test for this issue have doesn't have much in common with 
reality (since collection real implementation is different), so it works fine 
even in 1.4.3 version.
I hope it will be helpful. Thanks.

Original comment by pavlik.x...@gmail.com on 29 Nov 2013 at 3:44