Przeglądaj źródła

Modified DeliveryHistory to be immutable and filled with handling events at (Cargo) load time.

Implemented orphan delete of the old itinerary when a new itinerary is attached to a cargo.
peter_backlund 18 lat temu
rodzic
commit
0eda143206

+ 13
- 2
dddsample/src/main/java/se/citerus/dddsample/domain/Cargo.java Wyświetl plik

@@ -24,7 +24,7 @@ public final class Cargo {
24 24
   private Location destination;
25 25
 
26 26
   @Transient
27
-  private final DeliveryHistory deliveryHistory = new DeliveryHistory();
27
+  private DeliveryHistory deliveryHistory = DeliveryHistory.EMPTY_DELIVERY_HISTORY;
28 28
 
29 29
   @ManyToOne(cascade = CascadeType.ALL)
30 30
   private Itinerary itinerary;
@@ -121,6 +121,18 @@ public final class Cargo {
121 121
     this.itinerary = itinerary;
122 122
   }
123 123
 
124
+  public void removeItinerary() {
125
+    this.itinerary = null;
126
+  }
127
+
128
+  /**
129
+   * @param deliveryHistory Cargo delivery history
130
+   */
131
+  public void setDeliveryHistory(final DeliveryHistory deliveryHistory) {
132
+    Validate.notNull(deliveryHistory);
133
+    this.deliveryHistory = deliveryHistory;
134
+  }
135
+
124 136
   /**
125 137
    * Check if cargo is misdirected.
126 138
    * <p/>
@@ -201,5 +213,4 @@ public final class Cargo {
201 213
   Cargo() {
202 214
     // Needed by Hibernate
203 215
   }
204
-
205 216
 }

+ 12
- 3
dddsample/src/main/java/se/citerus/dddsample/domain/DeliveryHistory.java Wyświetl plik

@@ -11,25 +11,32 @@ import java.util.*;
11 11
  */
12 12
 public final class DeliveryHistory {
13 13
 
14
-  private final Set<HandlingEvent> events = new HashSet<HandlingEvent>();
14
+  private final Set<HandlingEvent> events;
15
+
16
+  public static final DeliveryHistory EMPTY_DELIVERY_HISTORY = new DeliveryHistory(Collections.EMPTY_SET);
17
+
18
+
19
+  public DeliveryHistory(final Collection<HandlingEvent> events) {
20
+    this.events = new HashSet<HandlingEvent>(events);
21
+  }
15 22
 
16 23
   /**
17 24
    * Adds all HandlingEvent to the delivery history.
18 25
    *
19 26
    * @param events events to add
20
-   */
21 27
   public void addAllEvents(final Collection<HandlingEvent> events) {
22 28
     this.events.addAll(events);
23 29
   }
30
+   */
24 31
 
25 32
   /**
26 33
    * Adds a HandlingEvent to the delivery history.
27 34
    *
28 35
    * @param event event to add.
29
-   */
30 36
   public void addEvent(final HandlingEvent event) {
31 37
     this.events.add(event);
32 38
   }
39
+   */
33 40
 
34 41
   /**
35 42
    * @return An <b>unmodifiable</b> list of handling events, ordered by the time the events occured.
@@ -110,8 +117,10 @@ public final class DeliveryHistory {
110 117
     return events.hashCode();
111 118
   }
112 119
 
120
+  /*
113 121
   DeliveryHistory() {
114 122
     // Needed by Hibernate
115 123
   }
124
+  */
116 125
 
117 126
 }

+ 1
- 0
dddsample/src/main/java/se/citerus/dddsample/domain/HandlingEvent.java Wyświetl plik

@@ -131,6 +131,7 @@ public final class HandlingEvent {
131 131
     return this.cargo;
132 132
   }
133 133
 
134
+  @Override
134 135
   public boolean equals(final Object o) {
135 136
     if (this == o) return true;
136 137
     if (o == null || getClass() != o.getClass()) return false;

+ 1
- 1
dddsample/src/main/java/se/citerus/dddsample/domain/Itinerary.java Wyświetl plik

@@ -21,7 +21,7 @@ public final class Itinerary {
21 21
   @JoinColumn(name = "itinerary_id")
22 22
   private List<Leg> legs = Collections.emptyList();
23 23
 
24
-  public static final Itinerary EMPTY_ITINERARY = new Itinerary();
24
+  static final Itinerary EMPTY_ITINERARY = new Itinerary();
25 25
 
26 26
   /**
27 27
    * Constructor.

+ 8
- 1
dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepository.java Wyświetl plik

@@ -1,6 +1,7 @@
1 1
 package se.citerus.dddsample.repository;
2 2
 
3 3
 import se.citerus.dddsample.domain.Cargo;
4
+import se.citerus.dddsample.domain.Itinerary;
4 5
 import se.citerus.dddsample.domain.TrackingId;
5 6
 
6 7
 import java.util.List;
@@ -25,7 +26,7 @@ public interface CargoRepository {
25 26
   /**
26 27
    * Saves given cargo.
27 28
    *
28
-   * @param cargo Cargo to save.
29
+   * @param cargo cargo to save
29 30
    */
30 31
   void save(Cargo cargo);
31 32
 
@@ -34,4 +35,10 @@ public interface CargoRepository {
34 35
    */
35 36
   TrackingId nextTrackingId();
36 37
 
38
+  /**
39
+   * Deletes an itinerary.
40
+   *
41
+   * @param itinerary itinerary to delete
42
+   */
43
+  void deleteItinerary(Itinerary itinerary);
37 44
 }

+ 17
- 1
dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepositoryHibernate.java Wyświetl plik

@@ -2,6 +2,8 @@ package se.citerus.dddsample.repository;
2 2
 
3 3
 import org.springframework.stereotype.Repository;
4 4
 import se.citerus.dddsample.domain.Cargo;
5
+import se.citerus.dddsample.domain.DeliveryHistory;
6
+import se.citerus.dddsample.domain.Itinerary;
5 7
 import se.citerus.dddsample.domain.TrackingId;
6 8
 
7 9
 import java.util.List;
@@ -26,10 +28,17 @@ public class CargoRepositoryHibernate extends HibernateRepository implements Car
26 28
     /*  There's no OR-mapped relation between the cargo delivery history and its handling events
27 29
         because the handling events are in a different aggregate.
28 30
 
31
+        TODO: investigate the following scenario to motivate this construction 
32
+        If we had to use pessimistic locking on cargo,
33
+        it might be cumbersome to map the relation between cargo and handling event,
34
+        since we want to be able to insert handling events regardless of locking status on cargo.
35
+
29 36
         If this extra database call were a problem, you might want to use a different model.
30 37
         For example, you could calculate the effect/status of the cargo and store it separate from the
31 38
         handling events. */
32
-    cargo.deliveryHistory().addAllEvents(handlingEventRepository.findEventsForCargo(tid));
39
+    DeliveryHistory deliveryHistory = new DeliveryHistory(handlingEventRepository.findEventsForCargo(tid));
40
+    cargo.setDeliveryHistory(deliveryHistory);
41
+
33 42
     return cargo;
34 43
   }
35 44
 
@@ -48,6 +57,13 @@ public class CargoRepositoryHibernate extends HibernateRepository implements Car
48 57
     );
49 58
   }
50 59
 
60
+  public void deleteItinerary(Itinerary itinerary) {
61
+    // Itinerary should be mapped to cascade deletes to all its legs
62
+    if (itinerary != null) {
63
+      getSession().delete(itinerary);
64
+    }
65
+  }
66
+
51 67
   public List<Cargo> findAll() {
52 68
     return getSession().createQuery("from Cargo").list();
53 69
   }

+ 4
- 0
dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepositoryInMem.java Wyświetl plik

@@ -2,6 +2,7 @@ package se.citerus.dddsample.repository;
2 2
 
3 3
 import org.springframework.dao.DataRetrievalFailureException;
4 4
 import se.citerus.dddsample.domain.Cargo;
5
+import se.citerus.dddsample.domain.Itinerary;
5 6
 import se.citerus.dddsample.domain.TrackingId;
6 7
 
7 8
 import java.util.HashMap;
@@ -46,6 +47,9 @@ public class CargoRepositoryInMem implements CargoRepository {
46 47
     return new TrackingId(UUID.randomUUID().toString());
47 48
   }
48 49
 
50
+  public void deleteItinerary(Itinerary itinerary) {
51
+  }
52
+
49 53
   public List<Cargo> findAll() {
50 54
     return null;  //To change body of implemented methods use File | Settings | File Templates.
51 55
   }

+ 5
- 2
dddsample/src/main/java/se/citerus/dddsample/service/CargoServiceImpl.java Wyświetl plik

@@ -117,6 +117,7 @@ public final class CargoServiceImpl implements CargoService {
117 117
     Validate.notNull(trackingId);
118 118
     Validate.notNull(dto);
119 119
 
120
+    // TODO: findAndLock, to illustrate locking problem vs. HandlingEvent?
120 121
     final Cargo cargo = cargoRepository.find(trackingId);
121 122
     if (cargo == null) {
122 123
       throw new IllegalArgumentException("Can't assign itinerary to non-existing cargo " + trackingId);
@@ -125,10 +126,12 @@ public final class CargoServiceImpl implements CargoService {
125 126
     final ItineraryCandidateDTOAssembler itineraryCandidateDTOAssembler = new ItineraryCandidateDTOAssembler();
126 127
     final Itinerary newItinerary = itineraryCandidateDTOAssembler.fromDTO(dto, carrierMovementRepository, locationRepository);
127 128
 
128
-    /* TODO: delete orphaned itinerary
129
+    // Delete orphaned itinerary
129 130
     final Itinerary oldItinerary = cargo.itinerary();
130 131
     cargoRepository.deleteItinerary(oldItinerary);
131
-    */
132
+    cargo.removeItinerary();
133
+
134
+    // Assign the new itinerary to the cargo
132 135
     cargo.setItinerary(newItinerary);
133 136
     cargoRepository.save(cargo);
134 137
   }

+ 48
- 38
dddsample/src/test/java/se/citerus/dddsample/domain/CargoTest.java Wyświetl plik

@@ -6,18 +6,10 @@ import static se.citerus.dddsample.domain.SampleLocations.*;
6 6
 import java.text.DateFormat;
7 7
 import java.text.ParseException;
8 8
 import java.text.SimpleDateFormat;
9
-import java.util.ArrayList;
10
-import java.util.Collection;
11
-import java.util.Date;
9
+import java.util.*;
12 10
 
13 11
 public class CargoTest extends TestCase {
14
-
15
-  // TODO:
16
-  // it seems that events are not added to the system by cargo.deliveryHistory().addEvent(),
17
-  // but rather new HandlingEvents are stored and associated with its cargo. This test should
18
-  // work against the repositories or the service layer. The delivery history of a cargo should be
19
-  // read-only from the cargo end. // PeBa
20
-
12
+  private Set<HandlingEvent> events;
21 13
 
22 14
   public void testlastKnownLocationUnknownWhenNoEvents() throws Exception {
23 15
     Cargo cargo = new Cargo(new TrackingId("XYZ"), STOCKHOLM, MELBOURNE);
@@ -73,6 +65,10 @@ public class CargoTest extends TestCase {
73 65
     assertFalse("Cargos are not equal when TrackingID differ", c1.equals(c2));
74 66
   }
75 67
 
68
+  protected void setUp() throws Exception {
69
+    events = new HashSet<HandlingEvent>();
70
+  }
71
+
76 72
   public void testIsUnloadedAtFinalDestination() throws Exception {
77 73
     assertFalse(new Cargo().isUnloadedAtDestination());
78 74
 
@@ -80,25 +76,29 @@ public class CargoTest extends TestCase {
80 76
     assertFalse(cargo.isUnloadedAtDestination());
81 77
 
82 78
     // Adding an event unrelated to unloading at final destination
83
-    cargo.deliveryHistory().addEvent(
79
+    events.add(
84 80
       new HandlingEvent(cargo, new Date(), new Date(), HandlingEvent.Type.RECEIVE, HANGZOU, null));
81
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
85 82
     assertFalse(cargo.isUnloadedAtDestination());
86 83
 
87 84
     CarrierMovement cm1 = new CarrierMovement(new CarrierMovementId("CM1"), HANGZOU, NEWYORK);
88 85
 
89 86
     // Adding an unload event, but not at the final destination
90
-    cargo.deliveryHistory().addEvent(
87
+    events.add(
91 88
       new HandlingEvent(cargo, new Date(), new Date(), HandlingEvent.Type.UNLOAD, TOKYO, cm1));
89
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
92 90
     assertFalse(cargo.isUnloadedAtDestination());
93 91
 
94 92
     // Adding an event in the final destination, but not unload
95
-    cargo.deliveryHistory().addEvent(
93
+    events.add(
96 94
       new HandlingEvent(cargo, new Date(), new Date(), HandlingEvent.Type.CUSTOMS, NEWYORK, null));
95
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
97 96
     assertFalse(cargo.isUnloadedAtDestination());
98 97
 
99 98
     // Finally, cargo is unloaded at final destination
100
-    cargo.deliveryHistory().addEvent(
99
+    events.add(
101 100
       new HandlingEvent(cargo, new Date(), new Date(), HandlingEvent.Type.UNLOAD, NEWYORK, cm1));
101
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
102 102
     assertTrue(cargo.isUnloadedAtDestination());
103 103
   }
104 104
 
@@ -129,7 +129,8 @@ public class CargoTest extends TestCase {
129 129
     final Cargo cargo = new Cargo(new TrackingId("XYZ"), STOCKHOLM, MELBOURNE);
130 130
 
131 131
     HandlingEvent he = new HandlingEvent(cargo, getDate("2007-12-01"), new Date(), HandlingEvent.Type.RECEIVE, STOCKHOLM, null);
132
-    cargo.deliveryHistory().addEvent(he);
132
+    events.add(he);
133
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
133 134
 
134 135
     return cargo;
135 136
   }
@@ -137,7 +138,8 @@ public class CargoTest extends TestCase {
137 138
   private Cargo populateCargoClaimedMelbourne() throws Exception {
138 139
     final Cargo cargo = populateCargoOffMelbourne();
139 140
 
140
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-09"), new Date(), HandlingEvent.Type.CLAIM, MELBOURNE, null));
141
+    events.add(new HandlingEvent(cargo, getDate("2007-12-09"), new Date(), HandlingEvent.Type.CLAIM, MELBOURNE, null));
142
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
141 143
 
142 144
     return cargo;
143 145
   }
@@ -148,15 +150,16 @@ public class CargoTest extends TestCase {
148 150
     final CarrierMovement stockholmToHamburg = new CarrierMovement(
149 151
        new CarrierMovementId("CAR_001"), STOCKHOLM, HAMBURG);
150 152
 
151
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-01"), new Date(), HandlingEvent.Type.LOAD, STOCKHOLM, stockholmToHamburg));
152
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-02"), new Date(), HandlingEvent.Type.UNLOAD, HAMBURG, stockholmToHamburg));
153
+    events.add(new HandlingEvent(cargo, getDate("2007-12-01"), new Date(), HandlingEvent.Type.LOAD, STOCKHOLM, stockholmToHamburg));
154
+    events.add(new HandlingEvent(cargo, getDate("2007-12-02"), new Date(), HandlingEvent.Type.UNLOAD, HAMBURG, stockholmToHamburg));
153 155
 
154 156
     final CarrierMovement hamburgToHongKong = new CarrierMovement(
155 157
        new CarrierMovementId("CAR_001"), HAMBURG, HONGKONG);
156 158
 
157
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-03"), new Date(), HandlingEvent.Type.LOAD, HAMBURG, hamburgToHongKong));
158
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-04"), new Date(), HandlingEvent.Type.UNLOAD, HONGKONG, hamburgToHongKong));
159
+    events.add(new HandlingEvent(cargo, getDate("2007-12-03"), new Date(), HandlingEvent.Type.LOAD, HAMBURG, hamburgToHongKong));
160
+    events.add(new HandlingEvent(cargo, getDate("2007-12-04"), new Date(), HandlingEvent.Type.UNLOAD, HONGKONG, hamburgToHongKong));
159 161
 
162
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
160 163
     return cargo;
161 164
   }
162 165
 
@@ -166,14 +169,15 @@ public class CargoTest extends TestCase {
166 169
     final CarrierMovement stockholmToHamburg = new CarrierMovement(
167 170
        new CarrierMovementId("CAR_001"), STOCKHOLM, HAMBURG);
168 171
 
169
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-01"), new Date(), HandlingEvent.Type.LOAD, STOCKHOLM, stockholmToHamburg));
170
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-02"), new Date(), HandlingEvent.Type.UNLOAD, HAMBURG, stockholmToHamburg));
172
+    events.add(new HandlingEvent(cargo, getDate("2007-12-01"), new Date(), HandlingEvent.Type.LOAD, STOCKHOLM, stockholmToHamburg));
173
+    events.add(new HandlingEvent(cargo, getDate("2007-12-02"), new Date(), HandlingEvent.Type.UNLOAD, HAMBURG, stockholmToHamburg));
171 174
 
172 175
     final CarrierMovement hamburgToHongKong = new CarrierMovement(
173 176
        new CarrierMovementId("CAR_001"), HAMBURG, HONGKONG);
174 177
 
175
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-03"), new Date(), HandlingEvent.Type.LOAD, HAMBURG, hamburgToHongKong));
178
+    events.add(new HandlingEvent(cargo, getDate("2007-12-03"), new Date(), HandlingEvent.Type.LOAD, HAMBURG, hamburgToHongKong));
176 179
 
180
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
177 181
     return cargo;
178 182
   }
179 183
 
@@ -183,21 +187,22 @@ public class CargoTest extends TestCase {
183 187
     final CarrierMovement stockholmToHamburg = new CarrierMovement(
184 188
        new CarrierMovementId("CAR_001"), STOCKHOLM, HAMBURG);
185 189
 
186
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-01"), new Date(), HandlingEvent.Type.LOAD, STOCKHOLM, stockholmToHamburg));
187
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-02"), new Date(), HandlingEvent.Type.UNLOAD, HAMBURG, stockholmToHamburg));
190
+    events.add(new HandlingEvent(cargo, getDate("2007-12-01"), new Date(), HandlingEvent.Type.LOAD, STOCKHOLM, stockholmToHamburg));
191
+    events.add(new HandlingEvent(cargo, getDate("2007-12-02"), new Date(), HandlingEvent.Type.UNLOAD, HAMBURG, stockholmToHamburg));
188 192
 
189 193
     final CarrierMovement hamburgToHongKong = new CarrierMovement(
190 194
        new CarrierMovementId("CAR_001"), HAMBURG, HONGKONG);
191 195
 
192
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-03"), new Date(), HandlingEvent.Type.LOAD, HAMBURG, hamburgToHongKong));
193
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-04"), new Date(), HandlingEvent.Type.UNLOAD, HONGKONG, hamburgToHongKong));
196
+    events.add(new HandlingEvent(cargo, getDate("2007-12-03"), new Date(), HandlingEvent.Type.LOAD, HAMBURG, hamburgToHongKong));
197
+    events.add(new HandlingEvent(cargo, getDate("2007-12-04"), new Date(), HandlingEvent.Type.UNLOAD, HONGKONG, hamburgToHongKong));
194 198
 
195 199
     final CarrierMovement hongKongToMelbourne = new CarrierMovement(
196 200
        new CarrierMovementId("CAR_001"), HONGKONG, MELBOURNE);
197 201
 
198
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-05"), new Date(), HandlingEvent.Type.LOAD, HONGKONG, hongKongToMelbourne));
199
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-07"), new Date(), HandlingEvent.Type.UNLOAD, MELBOURNE, hongKongToMelbourne));
202
+    events.add(new HandlingEvent(cargo, getDate("2007-12-05"), new Date(), HandlingEvent.Type.LOAD, HONGKONG, hongKongToMelbourne));
203
+    events.add(new HandlingEvent(cargo, getDate("2007-12-07"), new Date(), HandlingEvent.Type.UNLOAD, MELBOURNE, hongKongToMelbourne));
200 204
 
205
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
201 206
     return cargo;
202 207
   }
203 208
 
@@ -207,20 +212,21 @@ public class CargoTest extends TestCase {
207 212
     final CarrierMovement stockholmToHamburg = new CarrierMovement(
208 213
        new CarrierMovementId("CAR_001"), STOCKHOLM, HAMBURG);
209 214
 
210
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-01"), new Date(), HandlingEvent.Type.LOAD, STOCKHOLM, stockholmToHamburg));
211
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-02"), new Date(), HandlingEvent.Type.UNLOAD, HAMBURG, stockholmToHamburg));
215
+    events.add(new HandlingEvent(cargo, getDate("2007-12-01"), new Date(), HandlingEvent.Type.LOAD, STOCKHOLM, stockholmToHamburg));
216
+    events.add(new HandlingEvent(cargo, getDate("2007-12-02"), new Date(), HandlingEvent.Type.UNLOAD, HAMBURG, stockholmToHamburg));
212 217
 
213 218
     final CarrierMovement hamburgToHongKong = new CarrierMovement(
214 219
        new CarrierMovementId("CAR_001"), HAMBURG, HONGKONG);
215 220
 
216
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-03"), new Date(), HandlingEvent.Type.LOAD, HAMBURG, hamburgToHongKong));
217
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-04"), new Date(), HandlingEvent.Type.UNLOAD, HONGKONG, hamburgToHongKong));
221
+    events.add(new HandlingEvent(cargo, getDate("2007-12-03"), new Date(), HandlingEvent.Type.LOAD, HAMBURG, hamburgToHongKong));
222
+    events.add(new HandlingEvent(cargo, getDate("2007-12-04"), new Date(), HandlingEvent.Type.UNLOAD, HONGKONG, hamburgToHongKong));
218 223
 
219 224
     final CarrierMovement hongKongToMelbourne = new CarrierMovement(
220 225
        new CarrierMovementId("CAR_001"), HONGKONG, MELBOURNE);
221 226
 
222
-    cargo.deliveryHistory().addEvent(new HandlingEvent(cargo, getDate("2007-12-05"), new Date(), HandlingEvent.Type.LOAD, HONGKONG, hongKongToMelbourne));
227
+    events.add(new HandlingEvent(cargo, getDate("2007-12-05"), new Date(), HandlingEvent.Type.LOAD, HONGKONG, hongKongToMelbourne));
223 228
 
229
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
224 230
     return cargo;
225 231
   }
226 232
 
@@ -249,7 +255,8 @@ public class CargoTest extends TestCase {
249 255
     handlingEvents.add(new HandlingEvent(cargo, new Date(110), new Date(120), HandlingEvent.Type.CLAIM, GOTHENBURG, null));
250 256
     handlingEvents.add(new HandlingEvent(cargo, new Date(130), new Date(140), HandlingEvent.Type.CUSTOMS, GOTHENBURG, null));
251 257
 
252
-    cargo.deliveryHistory().addAllEvents(handlingEvents);
258
+    events.addAll(handlingEvents);
259
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
253 260
     assertFalse(cargo.isMisdirected());
254 261
 
255 262
     //Try a couple of failing ones
@@ -258,7 +265,8 @@ public class CargoTest extends TestCase {
258 265
     handlingEvents = new ArrayList<HandlingEvent>();
259 266
 
260 267
     handlingEvents.add(new HandlingEvent(cargo, new Date(), new Date(), HandlingEvent.Type.RECEIVE, HANGZOU, null));
261
-    cargo.deliveryHistory().addAllEvents(handlingEvents);
268
+    events.addAll(handlingEvents);
269
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
262 270
     assertTrue(cargo.isMisdirected());
263 271
 
264 272
 
@@ -270,7 +278,8 @@ public class CargoTest extends TestCase {
270 278
     handlingEvents.add(new HandlingEvent(cargo, new Date(50), new Date(60), HandlingEvent.Type.UNLOAD, ROTTERDAM, abc));
271 279
     handlingEvents.add(new HandlingEvent(cargo, new Date(70), new Date(80), HandlingEvent.Type.LOAD, ROTTERDAM, ghi));
272 280
 
273
-    cargo.deliveryHistory().addAllEvents(handlingEvents);
281
+    events.addAll(handlingEvents);
282
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
274 283
     assertTrue(cargo.isMisdirected());
275 284
 
276 285
 
@@ -282,7 +291,8 @@ public class CargoTest extends TestCase {
282 291
     handlingEvents.add(new HandlingEvent(cargo, new Date(50), new Date(60), HandlingEvent.Type.UNLOAD, ROTTERDAM, abc));
283 292
     handlingEvents.add(new HandlingEvent(cargo, new Date(), new Date(), HandlingEvent.Type.CLAIM, ROTTERDAM, null));
284 293
 
285
-    cargo.deliveryHistory().addAllEvents(handlingEvents);
294
+    events.addAll(handlingEvents);
295
+    cargo.setDeliveryHistory(new DeliveryHistory(events));
286 296
     assertTrue(cargo.isMisdirected());
287 297
   }
288 298
 

+ 18
- 14
dddsample/src/test/java/se/citerus/dddsample/domain/DeliveryHistoryTest.java Wyświetl plik

@@ -5,17 +5,13 @@ import static se.citerus.dddsample.domain.SampleLocations.*;
5 5
 
6 6
 import java.text.DateFormat;
7 7
 import java.text.SimpleDateFormat;
8
-import java.util.Arrays;
9
-import java.util.Date;
10
-import java.util.List;
8
+import java.util.*;
11 9
 
12 10
 public class DeliveryHistoryTest extends TestCase {
13 11
 
14 12
   private Cargo cargo = new Cargo(new TrackingId("XYZ"), HONGKONG, NEWYORK);
15 13
 
16 14
   public void testEvensOrderedByTimeOccured() throws Exception {
17
-    DeliveryHistory dh = new DeliveryHistory();
18
-    assertTrue(dh.eventsOrderedByCompletionTime().isEmpty());
19 15
 
20 16
     DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
21 17
     CarrierMovement carrierMovement = new CarrierMovement(new CarrierMovementId("CAR_001"), HONGKONG, NEWYORK);
@@ -23,7 +19,7 @@ public class DeliveryHistoryTest extends TestCase {
23 19
     HandlingEvent he2 = new HandlingEvent(cargo, df.parse("2010-01-01"), new Date(), HandlingEvent.Type.LOAD, NEWYORK, carrierMovement);
24 20
     HandlingEvent he3 = new HandlingEvent(cargo, df.parse("2010-01-04"), new Date(), HandlingEvent.Type.CLAIM, HONGKONG, null);
25 21
     HandlingEvent he4 = new HandlingEvent(cargo, df.parse("2010-01-02"), new Date(), HandlingEvent.Type.UNLOAD, HONGKONG, carrierMovement);
26
-    dh.addAllEvents(Arrays.asList(he1, he2, he3, he4));
22
+    DeliveryHistory dh = new DeliveryHistory(Arrays.asList(he1, he2, he3, he4));
27 23
 
28 24
     List<HandlingEvent> orderEvents = dh.eventsOrderedByCompletionTime();
29 25
     assertEquals(4, orderEvents.size());
@@ -34,34 +30,42 @@ public class DeliveryHistoryTest extends TestCase {
34 30
   }
35 31
 
36 32
   public void testCargoStatusFromLastHandlingEvent() {
37
-    DeliveryHistory deliveryHistory = new DeliveryHistory();
33
+    Set<HandlingEvent> events = new HashSet<HandlingEvent>();
34
+    DeliveryHistory deliveryHistory = new DeliveryHistory(events);
38 35
 
39 36
     assertEquals(StatusCode.NOT_RECEIVED, deliveryHistory.status());
40 37
 
41
-    deliveryHistory.addEvent(new HandlingEvent(cargo, new Date(10), new Date(11), HandlingEvent.Type.RECEIVE, HAMBURG, null));
38
+    events.add(new HandlingEvent(cargo, new Date(10), new Date(11), HandlingEvent.Type.RECEIVE, HAMBURG, null));
39
+    deliveryHistory = new DeliveryHistory(events);
42 40
     assertEquals(StatusCode.IN_PORT, deliveryHistory.status());
43 41
 
44 42
     CarrierMovement carrierMovement = new CarrierMovement(new CarrierMovementId("ABC"), HAMBURG, HAMBURG);
45
-    deliveryHistory.addEvent(new HandlingEvent(cargo, new Date(20), new Date(21), HandlingEvent.Type.LOAD, HAMBURG, carrierMovement));
43
+    events.add(new HandlingEvent(cargo, new Date(20), new Date(21), HandlingEvent.Type.LOAD, HAMBURG, carrierMovement));
44
+    deliveryHistory = new DeliveryHistory(events);
46 45
     assertEquals(StatusCode.ONBOARD_CARRIER, deliveryHistory.status());
47 46
 
48
-    deliveryHistory.addEvent(new HandlingEvent(cargo, new Date(30), new Date(31), HandlingEvent.Type.UNLOAD, HAMBURG, carrierMovement));
47
+    events.add(new HandlingEvent(cargo, new Date(30), new Date(31), HandlingEvent.Type.UNLOAD, HAMBURG, carrierMovement));
48
+    deliveryHistory = new DeliveryHistory(events);
49 49
     assertEquals(StatusCode.IN_PORT, deliveryHistory.status());
50 50
 
51
-    deliveryHistory.addEvent(new HandlingEvent(cargo, new Date(40), new Date(41), HandlingEvent.Type.CLAIM, HAMBURG, null));
51
+    events.add(new HandlingEvent(cargo, new Date(40), new Date(41), HandlingEvent.Type.CLAIM, HAMBURG, null));
52
+    deliveryHistory = new DeliveryHistory(events);
52 53
     assertEquals(StatusCode.CLAIMED, deliveryHistory.status());
53 54
   }
54 55
 
55 56
   public void testCurrentLocation() throws Exception {
56
-    DeliveryHistory deliveryHistory = new DeliveryHistory();
57
+    Set<HandlingEvent> events = new HashSet<HandlingEvent>();
58
+    DeliveryHistory deliveryHistory = new DeliveryHistory(events);
57 59
 
58 60
     assertNull(deliveryHistory.currentLocation());
59 61
 
60
-    deliveryHistory.addEvent(new HandlingEvent(cargo, new Date(10), new Date(11), HandlingEvent.Type.RECEIVE, HAMBURG, null));
62
+    events.add(new HandlingEvent(cargo, new Date(10), new Date(11), HandlingEvent.Type.RECEIVE, HAMBURG, null));
63
+    deliveryHistory = new DeliveryHistory(events);
61 64
     assertEquals(HAMBURG, deliveryHistory.currentLocation());
62 65
 
63 66
     CarrierMovement carrierMovement = new CarrierMovement(new CarrierMovementId("ABC"), HAMBURG, HAMBURG);
64
-    deliveryHistory.addEvent(new HandlingEvent(cargo, new Date(20), new Date(21), HandlingEvent.Type.LOAD, HAMBURG, carrierMovement));
67
+    events.add(new HandlingEvent(cargo, new Date(20), new Date(21), HandlingEvent.Type.LOAD, HAMBURG, carrierMovement));
68
+    deliveryHistory = new DeliveryHistory(events);
65 69
     assertNull(deliveryHistory.currentLocation());
66 70
   }
67 71
 

+ 1
- 2
dddsample/src/test/java/se/citerus/dddsample/domain/TrackingScenarioTest.java Wyświetl plik

@@ -35,8 +35,7 @@ public class TrackingScenarioTest extends TestCase {
35 35
 
36 36
     final CarrierMovement hamburgToHongKong = new CarrierMovement(
37 37
             new CarrierMovementId("CAR_002"), HAMBURG, HONGKONG);
38
-    DeliveryHistory dh = new DeliveryHistory();
39
-    dh.addAllEvents(Arrays.asList(
38
+    DeliveryHistory dh = new DeliveryHistory(Arrays.asList(
40 39
             new HandlingEvent(cargo, getDate("2007-12-01"), new Date(), HandlingEvent.Type.LOAD, STOCKHOLM, stockholmToHamburg),
41 40
             new HandlingEvent(cargo, getDate("2007-12-02"), new Date(), HandlingEvent.Type.UNLOAD, HAMBURG, stockholmToHamburg),
42 41
             new HandlingEvent(cargo, getDate("2007-12-03"), new Date(), HandlingEvent.Type.LOAD, HAMBURG, hamburgToHongKong),

+ 20
- 0
dddsample/src/test/java/se/citerus/dddsample/repository/AbstractRepositoryTest.java Wyświetl plik

@@ -1,12 +1,15 @@
1 1
 package se.citerus.dddsample.repository;
2 2
 
3 3
 import org.hibernate.SessionFactory;
4
+import org.hibernate.classic.Session;
4 5
 import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
5 6
 import org.springframework.orm.hibernate3.HibernateTransactionManager;
6 7
 import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
7 8
 import org.springframework.transaction.support.TransactionTemplate;
8 9
 import se.citerus.dddsample.util.SampleDataGenerator;
9 10
 
11
+import java.lang.reflect.Field;
12
+
10 13
 public abstract class AbstractRepositoryTest extends AbstractTransactionalDataSourceSpringContextTests {
11 14
 
12 15
   SessionFactory sessionFactory;
@@ -41,4 +44,21 @@ public abstract class AbstractRepositoryTest extends AbstractTransactionalDataSo
41 44
     sjt = new SimpleJdbcTemplate(jdbcTemplate);
42 45
   }
43 46
 
47
+  protected Session getSession() {
48
+    return sessionFactory.getCurrentSession();
49
+  }
50
+
51
+  protected Long getLongId(Object o) {
52
+    if (getSession().contains(o)) {
53
+      return (Long) getSession().getIdentifier(o);
54
+    } else {
55
+      try {
56
+        Field id = o.getClass().getDeclaredField("id");
57
+        id.setAccessible(true);
58
+        return (Long) id.get(o);
59
+      } catch (Exception e) {
60
+        throw new RuntimeException(e);
61
+      }
62
+    }
63
+  }
44 64
 }

+ 20
- 4
dddsample/src/test/java/se/citerus/dddsample/repository/CargoRepositoryTest.java Wyświetl plik

@@ -6,6 +6,7 @@ import static se.citerus.dddsample.domain.HandlingEvent.Type.RECEIVE;
6 6
 import static se.citerus.dddsample.domain.SampleLocations.*;
7 7
 import se.citerus.dddsample.util.SampleDataGenerator;
8 8
 
9
+import java.util.Arrays;
9 10
 import java.util.Date;
10 11
 import java.util.List;
11 12
 import java.util.Map;
@@ -93,10 +94,10 @@ public class CargoRepositoryTest extends AbstractRepositoryTest {
93 94
 
94 95
     assertEquals("AAA", map.get("TRACKING_ID"));
95 96
 
96
-    Long originId = (Long) sessionFactory.getCurrentSession().getIdentifier(origin);
97
+    Long originId = getLongId(origin);
97 98
     assertEquals(originId, map.get("ORIGIN_ID"));
98 99
 
99
-    Long destinationId = (Long) sessionFactory.getCurrentSession().getIdentifier(destination);
100
+    Long destinationId = getLongId(destination);
100 101
     assertEquals(destinationId, map.get("DESTINATION_ID"));
101 102
 
102 103
     assertNull(map.get("ITINERARY_ID"));
@@ -117,13 +118,13 @@ public class CargoRepositoryTest extends AbstractRepositoryTest {
117 118
     HandlingEvent event = new HandlingEvent(cargo, new Date(), new Date(), HandlingEvent.Type.RECEIVE, origin, null);
118 119
     assertFalse(cargo.deliveryHistory().eventsOrderedByCompletionTime().contains(event));
119 120
 
120
-    cargo.deliveryHistory().addEvent(event);
121
+    cargo.setDeliveryHistory(new DeliveryHistory(Arrays.asList(event)));
121 122
     assertTrue(cargo.deliveryHistory().eventsOrderedByCompletionTime().contains(event));
122 123
 
123 124
     // Save cargo, evict from session and then re-load it - should not pick up the added event,
124 125
     // as it was never cascade-saved
125 126
     cargoRepository.save(cargo);
126
-    sessionFactory.getCurrentSession().evict(cargo);
127
+    getSession().evict(cargo);
127 128
 
128 129
     cargo = cargoRepository.find(cargo.trackingId());
129 130
     assertFalse(cargo.deliveryHistory().eventsOrderedByCompletionTime().contains(event));
@@ -145,4 +146,19 @@ public class CargoRepositoryTest extends AbstractRepositoryTest {
145 146
     assertFalse(trackingId.equals(trackingId2));
146 147
   }
147 148
 
149
+  public void testDeleteItinerary() {
150
+    Cargo cargo = cargoRepository.find(new TrackingId("FGH"));
151
+    Itinerary itinerary = cargo.itinerary();
152
+
153
+    cargoRepository.deleteItinerary(itinerary);
154
+    cargo.removeItinerary();
155
+
156
+    flush();
157
+    
158
+    Long itineraryId = getLongId(itinerary);
159
+    assertEquals(0, sjt.queryForInt("select count(*) from Itinerary where id = ?", itineraryId));
160
+    assertEquals(0, sjt.queryForInt("select count(*) from Leg where itinerary_id = ?", itineraryId));
161
+    assertNull(sjt.queryForMap("select * from Cargo where tracking_id = 'FGH'").get("ITINERARY_ID"));
162
+  }
163
+
148 164
 }

+ 2
- 1
dddsample/src/test/java/se/citerus/dddsample/service/CargoServiceTest.java Wyświetl plik

@@ -38,7 +38,8 @@ public class CargoServiceTest extends TestCase {
38 38
     HandlingEvent loaded = new HandlingEvent(cargo, new Date(12), new Date(25), HandlingEvent.Type.LOAD, STOCKHOLM, carrierMovement);
39 39
     HandlingEvent unloaded = new HandlingEvent(cargo, new Date(100), new Date(110), HandlingEvent.Type.UNLOAD, CHICAGO, carrierMovement);
40 40
     // Add out of order to verify ordering in DTO
41
-    cargo.deliveryHistory().addAllEvents(Arrays.asList(loaded, unloaded, claimed));
41
+    List<HandlingEvent> eventList = Arrays.asList(loaded, unloaded, claimed);
42
+    cargo.setDeliveryHistory(new DeliveryHistory(eventList));
42 43
 
43 44
     expect(cargoRepository.find(new TrackingId("XYZ"))).andReturn(cargo);
44 45