Skip to content

Commit e1e089b

Browse files
committed
Moved all transaction demarcation metadata to application layer instead of domain layer.
1 parent 5821cb4 commit e1e089b

File tree

9 files changed

+53
-52
lines changed

9 files changed

+53
-52
lines changed

dddsample/src/main/java/se/citerus/dddsample/application/messaging/HandlingEventMessageDelegate.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.apache.commons.logging.Log;
44
import org.apache.commons.logging.LogFactory;
5+
import org.springframework.transaction.annotation.Transactional;
56
import se.citerus.dddsample.domain.model.cargo.TrackingId;
67
import se.citerus.dddsample.domain.service.TrackingService;
78

@@ -22,6 +23,7 @@ public class HandlingEventMessageDelegate implements MessageListener {
2223
private TrackingService trackingService;
2324
private final Log logger = LogFactory.getLog(getClass());
2425

26+
@Transactional(readOnly = true)
2527
public void onMessage(final Message message) {
2628
if (logger.isDebugEnabled()) {
2729
logger.debug("Received message " + message);

dddsample/src/main/java/se/citerus/dddsample/application/remoting/BookingServiceFacadeImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package se.citerus.dddsample.application.remoting;
22

3+
import org.springframework.transaction.annotation.Transactional;
34
import se.citerus.dddsample.application.remoting.dto.CargoRoutingDTO;
45
import se.citerus.dddsample.application.remoting.dto.ItineraryCandidateDTO;
56
import se.citerus.dddsample.application.remoting.dto.LocationDTO;
@@ -35,28 +36,33 @@ public class BookingServiceFacadeImpl implements BookingServiceFacade {
3536
private CargoRepository cargoRepository;
3637
private CarrierMovementRepository carrierMovementRepository;
3738

39+
@Transactional(readOnly = true)
3840
public List<LocationDTO> listShippingLocations() {
3941
final List<Location> allLocations = locationRepository.findAll();
4042
final LocationDTOAssembler assembler = new LocationDTOAssembler();
4143
return assembler.toDTOList(allLocations);
4244
}
4345

46+
@Transactional(readOnly = false)
4447
public String registerNewCargo(String origin, String destination) {
4548
TrackingId trackingId = bookingService.bookNewCargo(new UnLocode(origin), new UnLocode(destination));
4649
return trackingId.idString();
4750
}
4851

52+
@Transactional(readOnly = true)
4953
public CargoRoutingDTO loadCargoForRouting(String trackingId) {
5054
final Cargo cargo = cargoRepository.find(new TrackingId(trackingId));
5155
final CargoRoutingDTOAssembler assembler = new CargoRoutingDTOAssembler();
5256
return assembler.toDTO(cargo);
5357
}
5458

59+
@Transactional(readOnly = false)
5560
public void assignCargoToRoute(String trackingId, ItineraryCandidateDTO itineraryCandidateDTO) {
5661
final Itinerary itinerary = new ItineraryCandidateDTOAssembler().fromDTO(itineraryCandidateDTO, carrierMovementRepository, locationRepository);
5762
bookingService.assignCargoToRoute(new TrackingId(trackingId), itinerary);
5863
}
5964

65+
@Transactional(readOnly = true)
6066
public List<CargoRoutingDTO> listAllCargos() {
6167
final List<Cargo> cargoList = cargoRepository.findAll();
6268
final List<CargoRoutingDTO> dtoList = new ArrayList<CargoRoutingDTO>(cargoList.size());
@@ -67,6 +73,7 @@ public List<CargoRoutingDTO> listAllCargos() {
6773
return dtoList;
6874
}
6975

76+
@Transactional(readOnly = true)
7077
public List<ItineraryCandidateDTO> requestPossibleRoutesForCargo(String trackingId) throws RemoteException {
7178
final List<Itinerary> itineraries = bookingService.requestPossibleRoutesForCargo(new TrackingId(trackingId));
7279

dddsample/src/main/java/se/citerus/dddsample/application/ws/HandlingEventServiceEndpointImpl.java

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@
33
import org.apache.commons.lang.StringUtils;
44
import org.apache.commons.logging.Log;
55
import org.apache.commons.logging.LogFactory;
6+
import org.springframework.transaction.PlatformTransactionManager;
7+
import org.springframework.transaction.TransactionStatus;
8+
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
9+
import org.springframework.transaction.support.TransactionTemplate;
610
import se.citerus.dddsample.domain.model.cargo.TrackingId;
711
import se.citerus.dddsample.domain.model.carrier.CarrierMovementId;
812
import se.citerus.dddsample.domain.model.handling.HandlingEvent;
913
import se.citerus.dddsample.domain.model.location.UnLocode;
1014
import se.citerus.dddsample.domain.service.HandlingEventService;
1115
import se.citerus.dddsample.domain.service.UnknownCarrierMovementIdException;
16+
import se.citerus.dddsample.domain.service.UnknownLocationException;
1217
import se.citerus.dddsample.domain.service.UnknownTrackingIdException;
1318

1419
import javax.jws.WebService;
@@ -20,41 +25,49 @@
2025
public class HandlingEventServiceEndpointImpl implements HandlingEventServiceEndpoint {
2126

2227
private HandlingEventService handlingEventService;
28+
private TransactionTemplate transactionTemplate;
2329
private final Log logger = LogFactory.getLog(getClass());
2430
protected static final String ISO_8601_FORMAT = "yyyy-mm-dd HH:MM:SS.SSS";
2531

2632
public void register(final String completionTime, final String trackingId, final String carrierMovementId,
2733
final String unlocode, final String eventType) {
2834
try {
29-
Date date = parseIso8601Date(completionTime);
30-
TrackingId tid = new TrackingId(trackingId);
31-
CarrierMovementId cid;
35+
final Date date = parseIso8601Date(completionTime);
36+
final TrackingId tid = new TrackingId(trackingId);
37+
final CarrierMovementId cid;
3238
if (StringUtils.isNotEmpty(carrierMovementId)) {
3339
cid = new CarrierMovementId(carrierMovementId);
3440
} else {
3541
cid = null;
3642
}
37-
HandlingEvent.Type type = parseEventType(eventType);
43+
final HandlingEvent.Type type = parseEventType(eventType);
3844

39-
UnLocode ul = new UnLocode(unlocode);
45+
final UnLocode ul = new UnLocode(unlocode);
4046

41-
handlingEventService.register(date, tid, cid, ul, type);
47+
// Using programmatic demarcation here due to weaving conflicts
48+
// between jax-ws and Spring transaction annotations
49+
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
50+
protected void doInTransactionWithoutResult(TransactionStatus status) {
51+
try {
52+
53+
handlingEventService.register(date, tid, cid, ul, type);
54+
55+
} catch (UnknownCarrierMovementIdException e) {
56+
handleUnknownCarrierMovementId(e);
57+
} catch (UnknownTrackingIdException e) {
58+
handleUnknownTrackingId(e);
59+
} catch (UnknownLocationException e) {
60+
handleOtherError(e);
61+
}
62+
}
63+
});
4264

4365
} catch (IllegalArgumentException iae) {
4466
handleIllegalArgument(iae);
45-
4667
} catch (ParseException pe) {
4768
handleInvalidDateFormat(completionTime);
48-
49-
} catch (UnknownTrackingIdException utid) {
50-
handleUnknownTrackingId(utid);
51-
52-
} catch (UnknownCarrierMovementIdException ucmi) {
53-
handleUnknownCarrierMovementId(ucmi);
54-
5569
} catch (InvalidEventTypeException iete) {
5670
handleInvalidEventType(iete);
57-
5871
} catch (Exception e) {
5972
handleOtherError(e);
6073
}
@@ -99,4 +112,9 @@ private Date parseIso8601Date(final String completionTime) throws ParseException
99112
public void setHandlingEventService(final HandlingEventService handlingEventService) {
100113
this.handlingEventService = handlingEventService;
101114
}
115+
116+
public void setTransactionManager(PlatformTransactionManager transactionManager) {
117+
transactionTemplate = new TransactionTemplate(transactionManager);
118+
}
119+
102120
}

dddsample/src/main/java/se/citerus/dddsample/domain/service/impl/BookingServiceImpl.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import org.apache.commons.lang.Validate;
44
import org.apache.commons.logging.Log;
55
import org.apache.commons.logging.LogFactory;
6-
import org.springframework.transaction.annotation.Transactional;
76
import se.citerus.dddsample.domain.model.cargo.*;
87
import se.citerus.dddsample.domain.model.location.Location;
98
import se.citerus.dddsample.domain.model.location.LocationRepository;
@@ -22,7 +21,6 @@ public final class BookingServiceImpl implements BookingService {
2221

2322
private final Log logger = LogFactory.getLog(getClass());
2423

25-
@Transactional(readOnly = false)
2624
public TrackingId bookNewCargo(final UnLocode originUnLocode, final UnLocode destinationUnLocode) {
2725
Validate.notNull(originUnLocode);
2826
Validate.notNull(destinationUnLocode);
@@ -38,7 +36,6 @@ public TrackingId bookNewCargo(final UnLocode originUnLocode, final UnLocode des
3836
return cargo.trackingId();
3937
}
4038

41-
@Transactional(readOnly = true)
4239
public List<Itinerary> requestPossibleRoutesForCargo(TrackingId trackingId) {
4340
Validate.notNull(trackingId);
4441

@@ -48,7 +45,6 @@ public List<Itinerary> requestPossibleRoutesForCargo(TrackingId trackingId) {
4845
return routingService.fetchRoutesForSpecification(routeSpecification);
4946
}
5047

51-
@Transactional(readOnly = false)
5248
public void assignCargoToRoute(final TrackingId trackingId, final Itinerary newItinerary) {
5349
Validate.notNull(trackingId);
5450
Validate.notNull(newItinerary);

dddsample/src/main/java/se/citerus/dddsample/domain/service/impl/HandlingEventServiceImpl.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package se.citerus.dddsample.domain.service.impl;
22

33
import org.apache.commons.lang.Validate;
4-
import org.springframework.transaction.annotation.Transactional;
54
import se.citerus.dddsample.domain.model.cargo.Cargo;
65
import se.citerus.dddsample.domain.model.cargo.CargoRepository;
76
import se.citerus.dddsample.domain.model.cargo.TrackingId;
@@ -24,7 +23,6 @@ public final class HandlingEventServiceImpl implements HandlingEventService {
2423
private LocationRepository locationRepository;
2524
private DomainEventNotifier domainEventNotifier;
2625

27-
@Transactional(readOnly = false)
2826
public void register(final Date completionTime, final TrackingId trackingId, final CarrierMovementId carrierMovementId,
2927
final UnLocode unlocode, final HandlingEvent.Type type)
3028
throws UnknownCarrierMovementIdException, UnknownTrackingIdException, UnknownLocationException {

dddsample/src/main/java/se/citerus/dddsample/domain/service/impl/TrackingServiceImpl.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import org.apache.commons.lang.Validate;
44
import org.apache.commons.logging.Log;
55
import org.apache.commons.logging.LogFactory;
6-
import org.springframework.transaction.annotation.Transactional;
76
import se.citerus.dddsample.domain.model.cargo.Cargo;
87
import se.citerus.dddsample.domain.model.cargo.CargoRepository;
98
import se.citerus.dddsample.domain.model.cargo.TrackingId;
@@ -15,14 +14,12 @@ public class TrackingServiceImpl implements TrackingService {
1514

1615
private final Log logger = LogFactory.getLog(getClass());
1716

18-
@Transactional(readOnly = true)
1917
public Cargo track(final TrackingId trackingId) {
2018
Validate.notNull(trackingId);
2119

2220
return cargoRepository.find(trackingId);
2321
}
2422

25-
@Transactional(readOnly = true)
2623
public void inspectCargo(final TrackingId trackingId) {
2724
Validate.notNull(trackingId);
2825

dddsample/src/main/resources/context-remote.xml

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44
xmlns:ws="http://jax-ws.dev.java.net/spring/core"
55
xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
66
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
7-
xmlns:aop="http://www.springframework.org/schema/aop"
87
xsi:schemaLocation="
98
http://jax-ws.dev.java.net/spring/core https://jax-ws.dev.java.net/spring/core.xsd
109
http://jax-ws.dev.java.net/spring/servlet https://jax-ws.dev.java.net/spring/servlet.xsd
11-
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
1210
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
1311

1412

@@ -26,35 +24,11 @@
2624

2725
<bean id="handlingEventServiceEndpoint" class="se.citerus.dddsample.application.ws.HandlingEventServiceEndpointImpl">
2826
<property name="handlingEventService" ref="handlingEventService"/>
27+
<property name="transactionManager" ref="transactionManager"/>
2928
</bean>
3029

3130

32-
<!-- Booking service facade -->
33-
34-
35-
<!-- Hibernate interceptor -->
36-
<bean id="hibernateInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor">
37-
<property name="sessionFactory" ref="sessionFactory"/>
38-
</bean>
39-
40-
<!-- Facade wrapped with Hibernate interceptor -->
41-
<bean id="bookingServiceFacade" class="org.springframework.aop.framework.ProxyFactoryBean">
42-
<property name="interceptorNames">
43-
<list>
44-
<value>hibernateInterceptor</value>
45-
</list>
46-
</property>
47-
<property name="target">
48-
<bean class="se.citerus.dddsample.application.remoting.BookingServiceFacadeImpl">
49-
<property name="bookingService" ref="bookingService"/>
50-
<property name="cargoRepository" ref="cargoRepository"/>
51-
<property name="locationRepository" ref="locationRepository"/>
52-
<property name="carrierMovementRepository" ref="carrierMovementRepository"/>
53-
</bean>
54-
</property>
55-
</bean>
56-
57-
<!-- RMI exposure -->
31+
<!-- RMI exposed booking service facade -->
5832
<bean id="rmiBookingServiceFacade" class="org.springframework.remoting.rmi.RmiServiceExporter">
5933
<property name="serviceInterface" value="se.citerus.dddsample.application.remoting.BookingServiceFacade"/>
6034
<property name="service" ref="bookingServiceFacade"/>

dddsample/src/main/resources/context-service.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,11 @@
3333
<property name="graphTraversalService" ref="graphTraversalService"/>
3434
</bean>
3535

36+
<bean id="bookingServiceFacade" class="se.citerus.dddsample.application.remoting.BookingServiceFacadeImpl">
37+
<property name="bookingService" ref="bookingService"/>
38+
<property name="cargoRepository" ref="cargoRepository"/>
39+
<property name="locationRepository" ref="locationRepository"/>
40+
<property name="carrierMovementRepository" ref="carrierMovementRepository"/>
41+
</bean>
42+
3643
</beans>

dddsample/src/test/java/se/citerus/dddsample/application/ws/HandlinEventServiceEndpointTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import junit.framework.TestCase;
44
import static org.easymock.EasyMock.*;
5+
import se.citerus.dddsample.application.service.InMemTransactionManager;
56
import se.citerus.dddsample.domain.model.cargo.TrackingId;
67
import se.citerus.dddsample.domain.model.carrier.CarrierMovementId;
78
import se.citerus.dddsample.domain.model.handling.HandlingEvent;
@@ -24,6 +25,7 @@ protected void setUp() throws Exception {
2425
handlingEventService = createMock(HandlingEventService.class);
2526
endpoint.setHandlingEventService(handlingEventService);
2627
sdf = new SimpleDateFormat(HandlingEventServiceEndpointImpl.ISO_8601_FORMAT);
28+
endpoint.setTransactionManager(new InMemTransactionManager());
2729
}
2830

2931
public void testRegisterValidEvent() throws Exception {

0 commit comments

Comments
 (0)