2525import java .util .stream .Stream ;
2626import org .seasar .doma .internal .util .Combinations ;
2727import org .seasar .doma .internal .util .Pair ;
28+ import org .seasar .doma .jdbc .EntityId ;
2829import org .seasar .doma .jdbc .command .Command ;
2930import org .seasar .doma .jdbc .command .SelectCommand ;
3031import org .seasar .doma .jdbc .entity .EntityType ;
4041 */
4142public class AggregateCommand <RESULT , ENTITY > implements Command <RESULT > {
4243 private final SelectQuery query ;
43- private final EntityType <ENTITY > entityType ;
44+ private final EntityType <ENTITY > rootEntityType ;
4445 private final StreamReducer <RESULT , ENTITY > streamReducer ;
4546 private final AggregateStrategyType aggregateStrategyType ;
4647
4748 public AggregateCommand (
4849 SelectQuery query ,
49- EntityType <ENTITY > entityType ,
50+ EntityType <ENTITY > rootEntityType ,
5051 StreamReducer <RESULT , ENTITY > streamReducer ,
5152 AggregateStrategyType aggregateStrategyType ) {
5253 this .query = Objects .requireNonNull (query );
53- this .entityType = Objects .requireNonNull (entityType );
54+ this .rootEntityType = Objects .requireNonNull (rootEntityType );
5455 this .streamReducer = Objects .requireNonNull (streamReducer );
5556 this .aggregateStrategyType = Objects .requireNonNull (aggregateStrategyType );
5657 }
5758
5859 @ Override
5960 public RESULT execute () {
60- Set <AggregateEntityCacheKey > rootEntityKeys = new LinkedHashSet <>();
61- Map <AggregateEntityCacheKey , Object > entityCache = new HashMap <>();
62- SelectCommand <List <AggregateEntityPool >> command =
61+ Set <EntityId > rootEntityIds = new LinkedHashSet <>();
62+ Map <EntityId , Object > entityCache = new HashMap <>();
63+ Combinations <AssociationEntityKey > combinations = new Combinations <>();
64+
65+ SelectCommand <List <AssociationEntityPool >> command =
6366 new SelectCommand <>(
6467 query ,
65- new AggregateEntityPoolIterationHandler (
66- entityType ,
68+ new AssociationEntityPoolIterationHandler (
69+ rootEntityType ,
6770 aggregateStrategyType ,
6871 query .isResultMappingEnsured (),
69- rootEntityKeys ,
72+ rootEntityIds ,
7073 entityCache ));
71- List <AggregateEntityPool > entityPools = command .execute ();
72-
73- Combinations <AggregateEntityKey > combinations = new Combinations <>();
74- for (AggregateEntityPool entityPool : entityPools ) {
75- Map <AggregatePathKey , AggregateEntityPoolEntry > associationCandidate = new HashMap <>();
76- for (AggregateEntityPoolEntry entry : entityPool ) {
77- associationCandidate .put (entry .entityKey ().pathKey (), entry );
78- }
79- associate (entityCache , combinations , associationCandidate );
74+ List <AssociationEntityPool > entityPools = command .execute ();
75+ for (AssociationEntityPool entityPool : entityPools ) {
76+ associate (entityCache , combinations , entityPool );
8077 }
8178
8279 @ SuppressWarnings ("unchecked" )
8380 Stream <ENTITY > stream =
8481 (Stream <ENTITY >)
85- rootEntityKeys .stream ()
82+ rootEntityIds .stream ()
8683 .map (entityCache ::get )
8784 .filter (Objects ::nonNull )
88- .filter (entityType .getEntityClass ()::isInstance );
85+ .filter (rootEntityType .getEntityClass ()::isInstance );
8986
9087 return streamReducer .reduce (stream );
9188 }
@@ -95,19 +92,19 @@ public RESULT execute() {
9592 * of linkage rules and updates the cache with newly associated entities.
9693 */
9794 private void associate (
98- Map <AggregateEntityCacheKey , Object > entityCache ,
99- Combinations <AggregateEntityKey > combinations ,
100- Map < AggregatePathKey , AggregateEntityPoolEntry > associationCandidate ) {
95+ Map <EntityId , Object > entityCache ,
96+ Combinations <AssociationEntityKey > combinations ,
97+ AssociationEntityPool entityPool ) {
10198
10299 for (AssociationLinkerType <?, ?> linkerType :
103100 aggregateStrategyType .getAssociationLinkerTypes ()) {
104- AggregateEntityPoolEntry source = associationCandidate .get (linkerType .getSourcePathKey ());
105- AggregateEntityPoolEntry target = associationCandidate .get (linkerType .getTargetPathKey ());
101+ AssociationEntityPoolEntry source = entityPool .get (linkerType .getSourcePathKey ());
102+ AssociationEntityPoolEntry target = entityPool .get (linkerType .getTargetPathKey ());
106103 if (source == null || target == null ) {
107104 continue ;
108105 }
109106
110- Pair <AggregateEntityKey , AggregateEntityKey > keyPair =
107+ Pair <AssociationEntityKey , AssociationEntityKey > keyPair =
111108 new Pair <>(source .entityKey (), target .entityKey ());
112109 if (combinations .contains (keyPair )) {
113110 continue ;
@@ -117,12 +114,10 @@ private void associate(
117114 @ SuppressWarnings ("unchecked" )
118115 BiFunction <Object , Object , Object > linker =
119116 (BiFunction <Object , Object , Object >) linkerType .getLinker ();
120- Object entity = linker .apply (source .entity (), target .entity ());
121- if (entity != null ) {
122- AggregateEntityCacheKey cacheKey = AggregateEntityCacheKey .of (source .entityKey ());
123- entityCache .replace (cacheKey , entity );
124- associationCandidate .replace (
125- source .pathKey (), new AggregateEntityPoolEntry (source .entityKey (), entity ));
117+ Object newEntity = linker .apply (source .entity (), target .entity ());
118+ if (newEntity != null && newEntity != source .entity ()) {
119+ entityCache .replace (source .entityId (), newEntity );
120+ entityPool .replace (new AssociationEntityPoolEntry (source .entityKey (), newEntity ));
126121 }
127122 }
128123 }
0 commit comments