# Spring + JPA @Transactional + ES Listener: Throwing exception rollbacks DB but does not cancel the persistence in ES

**URL:** https://discuss.elastic.co/t/spring-jpa-transactional-es-listener-throwing-exception-rollbacks-db-but-does-not-cancel-the-persistence-in-es/15236
**Category:** Elasticsearch
**Created:** [January 14, 2014, 4:27pm UTC](https://discuss.elastic.co/t/spring-jpa-transactional-es-listener-throwing-exception-rollbacks-db-but-does-not-cancel-the-persistence-in-es/15236 "2014-01-14T16:27:05Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Diego\_Sosa](https://avatars.discourse-cdn.com/v4/letter/d/47e85d/32.png) [@Diego\_Sosa](https://discuss.elastic.co/u/Diego_Sosa)
#### Post date: [January 14, 2014, 4:27pm UTC](https://discuss.elastic.co/t/spring-jpa-transactional-es-listener-throwing-exception-rollbacks-db-but-does-not-cancel-the-persistence-in-es/15236/1 "2014-01-14T16:27:05Z")

</div>

Hello everyone,

This is not a problem related solely to ES but to how to integrate it to  
Spring and JPA. The problem I am having is that I registered a few  
hibernate listeners to index/deindex the DB entities into Elastic Search  
once they have been persisted in the DB. The problem is that the listener  
onPostInsert method is called even if I throw an exception in the method  
that persists the entities and this method is marked as  
@Transactional(rollbackFor = {Throwable.class}). What happens? Entity gets  
into ES but DB is rollbacked.

My configuration is as follows:

\*The listener class: \*defines what to do whenever there is an insert,  
delete, update, etc. in the database.

public class ElasticSearchEventListener implements PostDeleteEventListener,  
PostInsertEventListener, PostUpdateEventListener {

```
@Override
public void onPostInsert(PostInsertEvent event) {
    log.debug("Listener indexing entity");
    try {
       updateElasticSearch(event.getEntity());
    } catch (Exception e) {
       log.debug("Error indexing object from listener");
       e.printStackTrace();
    }
}

.......}

```

\*The listener configurer class: \*attaches the listener class to the  
appropriate Hibernate events, for example: POST\_COMMIT\_INSERT

@Service @Log4jpublic class ListenerConfigurerImpl implements ListenerConfigurer {  
@Autowired  
private EntityManagerFactory entityManagerFactory;

```
@Autowired
private ElasticSearchEventListener listener;

@PostConstruct @Override
public void registerListeners() {
    log.debug("Registering event listeners");
    HibernateEntityManagerFactory hibernateEntityManagerFactory = (HibernateEntityManagerFactory) this.entityManagerFactory;
    SessionFactoryImpl sessionFactoryImpl = (SessionFactoryImpl) hibernateEntityManagerFactory.getSessionFactory();
    EventListenerRegistry registry = sessionFactoryImpl.getServiceRegistry().getService(EventListenerRegistry.class);
    registry.getEventListenerGroup(EventType.POST_COMMIT_INSERT).appendListener(listener);

    .......
}}

```

_A service class:_ a service method marked with @Transactional and throwing  
an exception on purpose.

@Service @Log4jpublic class ConversationServiceImpl implements ConversationService {

```
@Override        
@Transactional(rollbackFor = {Throwable.class})
public void quotePackage(Long userId, CustomQuoteDTO dto) {
    ......
    Conversation conversation = Conversation.createAndAssign(user, agency, type, subject);
    conversation = conversationRepository.save(conversation);
    Long conversationId = conversation.getId();

    throw new RuntimeException();
}}

```

Based on this configuration, I would be expecting that the entity is not  
saved neither in the DB nor Elastic Search. What happens is that the DB is  
rollbacks correctly but the listener is called despite that. It's like it  
does not know about the transaction been rollbacked. I found a bug related  
to this in the hibernate forums [https://hibernate.atlassian.net/browse/HHH-1582](https://hibernate.atlassian.net/browse/HHH-1582)  
but it's from 2006 and it is still open. Any ideas on how to solve this  
problem? Another way to implement the listener may be?

Thanks in advance.

--  
You received this message because you are subscribed to the Google Groups "elasticsearch" group.  
To unsubscribe from this group and stop receiving emails from it, send an email to [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
To view this discussion on the web visit [https://groups.google.com/d/msgid/elasticsearch/47c12659-f81a-4d49-8326-18157a5b16ed%40googlegroups.com](https://groups.google.com/d/msgid/elasticsearch/47c12659-f81a-4d49-8326-18157a5b16ed%40googlegroups.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<div class="post-metadata">

### Author: ![costin](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/costin/32/44950_2.png) [@costin](https://discuss.elastic.co/u/costin)
#### Post date: [January 14, 2014, 5:01pm UTC](https://discuss.elastic.co/t/spring-jpa-transactional-es-listener-throwing-exception-rollbacks-db-but-does-not-cancel-the-persistence-in-es/15236/2 "2014-01-14T17:01:38Z")

</div>

Hi,

Guessing here but make sure your ES writing happens last during commit and not post insert. The difference between the  
two is that the former means no exceptions have been triggered and the tx is about to be committed, the latter that the  
insert is successful but the tx is on-going and it can still be rolled back.

Looking at your code, you marked ES to be occur after an insert - so the behavior that you are seeing is correct.  
Considering using a Hibernate interceptor or even better, Spring's TransactionSynchronization#afterCommit.  
It all depends on how easy you can pass the contextual object between your app and the post commit hook...

On 14/01/2014 6:27 PM, Agustin Lopez wrote:

> Hello everyone,
> 
> This is not a problem related solely to ES but to how to integrate it to Spring and JPA. The problem I am having is that  
> I registered a few hibernate listeners to index/deindex the DB entities into Elastic Search once they have been  
> persisted in the DB. The problem is that the listener onPostInsert method is called even if I throw an exception in the  
> method that persists the entities and this method is marked as @Transactional(rollbackFor = {Throwable.class}). What  
> happens? Entity gets into ES but DB is rollbacked.
> 
> My configuration is as follows:
> 
> \*The listener class: \*defines what to do whenever there is an insert, delete, update, etc. in the database.
> 
> |public class ElasticSearchEventListener implements PostDeleteEventListener,  
> PostInsertEventListener, PostUpdateEventListener {
> 
> ```
> @Override
> public void onPostInsert(PostInsertEvent event) {
> log.debug("Listener indexing entity");
> try {
> updateElasticSearch(event.getEntity());
> } catch (Exception e) {
> log.debug("Error indexing object from listener");
> e.printStackTrace();
> }
> }
> 
> .......
> 
> ```
> 
> }|
> 
> - 
> - 
> 
> \*The listener configurer class: \*attaches the listener class to the appropriate Hibernate events, for example:  
> POST\_COMMIT\_INSERT
> 
> |@Service @Log4j  
> public class ListenerConfigurerImpl implements ListenerConfigurer {  
> @Autowired  
> private EntityManagerFactory entityManagerFactory;
> 
> ```
> @Autowired
> private ElasticSearchEventListener listener;
> 
> @PostConstruct @Override
> public void registerListeners() {
> log.debug("Registering event listeners");
> HibernateEntityManagerFactory hibernateEntityManagerFactory= (HibernateEntityManagerFactory) this.entityManagerFactory;
> SessionFactoryImpl sessionFactoryImpl= (SessionFactoryImpl) hibernateEntityManagerFactory.getSessionFactory();
> EventListenerRegistry registry= sessionFactoryImpl.getServiceRegistry().getService(EventListenerRegistry.class);
> registry.getEventListenerGroup(EventType.POST_COMMIT_INSERT).appendListener(listener);
> 
> .......
> }
> 
> ```
> 
> }|
> 
> - 
> - 
> 
> \*A service class:\*a service method marked with @Transactional and throwing an exception on purpose.
> 
> |@Service @Log4j  
> public class ConversationServiceImpl implements ConversationService {
> 
> ```
> @Override
> @Transactional(rollbackFor= {Throwable.class})
> public void quotePackage(Long userId, CustomQuoteDTO dto) {
> ......
> Conversation conversation= Conversation.createAndAssign(user, agency, type, subject);
> conversation= conversationRepository.save(conversation);
> Long conversationId= conversation.getId();
> 
> throw new RuntimeException();
> }
> 
> ```
> 
> }|
> 
> Based on this configuration, I would be expecting that the entity is not saved neither in the DB nor Elastic Search.  
> What happens is that the DB is rollbacks correctly but the listener is called despite that. It's like it does not know  
> about the transaction been rollbacked. I found a bug related to this in the hibernate forums  
> [[HHH-1582] - Hibernate JIRA](https://hibernate.atlassian.net/browse/HHH-1582) but it's from 2006 and it is still open.Any ideas on how to solve this  
> problem? Another way to implement the listener may be?
> 
> Thanks in advance.
> 
> --  
> You received this message because you are subscribed to the Google Groups "elasticsearch" group.  
> To unsubscribe from this group and stop receiving emails from it, send an email to  
> [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
> To view this discussion on the web visit  
> [https://groups.google.com/d/msgid/elasticsearch/47c12659-f81a-4d49-8326-18157a5b16ed%40googlegroups.com](https://groups.google.com/d/msgid/elasticsearch/47c12659-f81a-4d49-8326-18157a5b16ed%40googlegroups.com).  
> For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

--  
Costin

--  
You received this message because you are subscribed to the Google Groups "elasticsearch" group.  
To unsubscribe from this group and stop receiving emails from it, send an email to [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
To view this discussion on the web visit [https://groups.google.com/d/msgid/elasticsearch/52D56D72.6070006%40gmail.com](https://groups.google.com/d/msgid/elasticsearch/52D56D72.6070006%40gmail.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)
#### Post date: [July 6, 2017, 1:56am UTC](https://discuss.elastic.co/t/spring-jpa-transactional-es-listener-throwing-exception-rollbacks-db-but-does-not-cancel-the-persistence-in-es/15236/3 "2017-07-06T01:56:52Z")

</div>


