Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » JPA problem: wrong sql in first execution
JPA problem: wrong sql in first execution [message #665812] Sat, 16 April 2011 05:42 Go to next message
Massimo Ugues is currently offline 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
Re: JPA problem: wrong sql in first execution [message #665985 is a reply to message #665812] Mon, 18 April 2011 09:21 Go to previous message
James Sutherland is currently offline James Sutherland
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

Enable logging on finest to determine what is occurring.


James : Wiki : Book : Blog : Twitter
Previous Topic:MySQL JDBC URL
Next Topic:Separate project trouble
Goto Forum:
  


Current Time: Fri Aug 22 15:42:51 EDT 2014

Powered by FUDForum. Page generated in 0.02622 seconds