Home » Eclipse Projects » EclipseLink » JPA problem: wrong sql in first execution
JPA problem: wrong sql in first execution [message #665812] |
Sat, 16 April 2011 09:42 |
Massimo Ugues Messages: 10 Registered: January 2011 |
Junior Member |
|
|
Hallo all.
Hallo all. I have a java enterprise application with spring, spring-integration, jpa for persistence with eclipse-link deployed on oracle weblogic 10.3.
The application is event-driven: there's 1 MDB that reads from a JMS queue, call an EJB and creates a message that is handled with spring integration.
MDB-->EJB-->spring-integration gateway-->execution workflow based on the message nature.
MDB
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void onMessage(Message message) {
OnlineEventMessage<? extends Serializable> eventMessage = null;
try {
TextMessage textMessage = (TextMessage) message;
String stringMessage = textMessage.getText();
logger.debug("e' stato ricevuto il messaggio {}", stringMessage);
logger.debug("eventMessageParser {}", onlineEventMessageParser);
logger.debug("legacyEventMessageService {}", legacyEventMessageService);
EventMessageAnagrafica anagrafica = anagraficaParser.parse(stringMessage, true);
String multichannelId = anagrafica.getMultichannelId();
eventMessage = onlineEventMessageParser.parse(stringMessage, true);
MDC.put("multichannelId", multichannelId);
MDC.put("eventType", eventMessage.getEventType().getEventCode());
legacyEventMessageService.handle(eventMessage);
EJB
@Stateless
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class LegacyEventMessageLocalServiceImpl implements LegacyEventMessageLocalService {
@Autowired
@Qualifier("legacyEventMessageService")
private LegacyEventMessageService legacyEventMessageService;
/**
* @see it.alten.intesasanpaolo.contratto.services.messaging.nk.LegacyEventMessageLocalService#handle(it.alten.intesasanpaolo.contratto.domain.event.OnlineEventMessage)
*/
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public <T extends Serializable> void handle(OnlineEventMessage<T> eventMessage) {
legacyEventMessageService.handle(eventMessage);
}
}
Spring-integration gateway
@Service("legacyEventMessageService")
public class LegacyEventMessageService {
private final static Logger logger = LoggerFactory.getLogger(LegacyEventMessageService.class);
@Autowired
@Qualifier("onlineMessageGateway")
private OnlineMessageGateway eventMessageGateway;
/**
* Prende in carico il messaggio e ne delega la gestione all'apposito gateway.
*/
public <T extends Serializable> void handle(OnlineEventMessage<T> eventMessage) {
logger.debug("Manipolazione del messaggio {}", eventMessage.getIdEventMessage());
eventMessageGateway.handle(eventMessage);
}
}
After the gateway I have two spring integration components: 2 interceptors. The first interceptor persists the message, the second one updates it.
First interceptor:
public class EventMessagePersisterInterceptor extends ChannelInterceptorAdapter {
private final static Logger logger = LoggerFactory.getLogger(EventMessagePersisterInterceptor.class);
private GenericDao<OnlineEventMessage<?>, Long> eventMessageDao;
public GenericDao<OnlineEventMessage<?>, Long> getEventMessageDao() {
return eventMessageDao;
}
public void setEventMessageDao(GenericDao<OnlineEventMessage<?>, Long> eventMessageDao) {
this.eventMessageDao = eventMessageDao;
}
/**
* @see org.springframework.integration.channel.interceptor.ChannelInterceptorAdapter#preSend(org.springframework.integration.Message,
* org.springframework.integration.MessageChannel)
*/
@SuppressWarnings("unchecked")
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Message<?> preSend(Message<?> message, MessageChannel channel) {
logger.info("Intercettato messaggio {} ", message);
OnlineEventMessage<String> eventMessage = (OnlineEventMessage<String>) message.getPayload();
eventMessage.setEventState(EventState.PROCESSING);
if(eventMessage.getEventType().equals(EventType.ONLINE_NO_OPERATION) || eventMessage.getEventType().equals(EventType.ONLINE_TRASFERIMENTO_RAPPORTO)){
eventMessage.setEventMessageAnagrafica(null);
}
eventMessageDao.saveItem(eventMessage);
eventMessageDao.flush();
MDC.put("eventMessageId", eventMessage.getIdEventMessage());
logger.debug("Salvataggio messaggio effettuato");
return super.preSend(message, channel);
}
}
Second interceptor:
public class EventMessageUpdaterInterceptor extends ChannelInterceptorAdapter {
private final static Logger logger = LoggerFactory.getLogger(EventMessageUpdaterInterceptor.class);
@Autowired
@Qualifier("eventMessageDao")
private GenericDao<OnlineEventMessage<?>, Long> eventMessageDao;
@Autowired
@Qualifier("clienteDao")
private GenericDao<Cliente, ClienteId> clienteDao;
@Override
public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
logger.info("Intercettato messaggio, modifica event message anagrafica in corso");
OnlineEventMessage<?> eventMessage = (OnlineEventMessage<?>) message.getPayload();
eventMessage = eventMessageDao.getItemByID(eventMessage.getIdEventMessage());
// Change the status
eventMessageDao.updateItem(eventMessage);
eventMessageDao.flush();
logger.info("Salvataggio messaggio effettuato correttamente {}", eventMessage);
logger.info("Cleaning MDC map...");
MDC.put("eventMessageId", "");
MDC.put("eventType", "");
MDC.put("multichannelId", "");
super.postSend(message, channel, sent);
}
The correct jpa behaviour is this:
INSERT IGNORE INTO S_CONT_EVENT_MESSAGE (ID_EVENT_MESSAGE, EVENT_DATE, EVENT_STATE, EVENT_CODE, PAYLOAD, CRB_PAYLOAD) VALUES (?, ?, ?,?, ?, ?)
UPDATE S_CONT_EVENT_MESSAGE SET EVENT_STATE = ? WHERE (ID_EVENT_MESSAGE = ?)
And when application is correctly started it works in this way. The problem is that when the server starts, before going in RUNNING mode, if there is a message in the queue the MDB reads the message and instead of the INSERT and then the UPDATE it generates two INSERT:
INSERT IGNORE INTO S_CONT_EVENT_MESSAGE (ID_EVENT_MESSAGE, EVENT_DATE, EVENT_STATE, EVENT_CODE, PAYLOAD, CRB_PAYLOAD) VALUES (?, ?, ?,?, ?, ?)
INSERT IGNORE INTO S_CONT_EVENT_MESSAGE (ID_EVENT_MESSAGE, EVENT_DATE, EVENT_STATE, EVENT_CODE, PAYLOAD, CRB_PAYLOAD) VALUES (?, ?, ?,?, ?, ?)
Any idea? I read that JMS, JDBC and JTA services run in ADMIN state, before RUNNING. I don'tknow if this could be a problem. It seems that the first save is not shared between the eclipse-link cache... Kind regards
Massimo
|
|
| |
Goto Forum:
Current Time: Sat Apr 20 03:03:13 GMT 2024
Powered by FUDForum. Page generated in 0.03518 seconds
|