Lag between Spring #Transaction finish and actual DB commit - spring

I have a simple SpringBoot application, which is using SpringData and has the next structure
SlotConfigsController -> Repository (CrudRepository)
#RestController
#RequiredArgsConstructor
public class ConfigsController {
private final ConfigsRepository configsRepository;
#PostMapping(path = "/configs")
public ResponseEntity<Void> saveConfig(#RequestBody ConfigDto config) {
ConfigEntity config = CONFIGS_MAPPER.dtoToEntity(config);
configsRepository.save(config);
log.info("Transactional method finished");
}
}
Repository
#Repository
public interface ConfigsRepository extends CrudRepository<ConfigsEntity, Long> {
#Transactional
ConfigsEntity save(ConfigsEntity entity);
}
I started Postgres DB using docker-compose and enabled logs via
environment:
- EXTRA_CONF=log_statement=all
What I noticed during the log analysis is that the actual DB commit (inside the docker log) occurs after the log.info(...) call.
Here is the log from the code
17:12:11,856 TRACE [http-nio-8080-exec-2] [TransactionSynchronizationManager.java] - Clearing transaction synchronization
17:12:11,856 TRACE [http-nio-8080-exec-2] [TransactionSynchronizationManager.java] - Removed value [org.springframework.jdbc.datasource.ConnectionHolder#550de51c] for key [HikariDataSource (Hikari)] from thread [http-nio-8080-exec-2]
17:12:11,856 TRACE [http-nio-8080-exec-2] [TransactionSynchronizationManager.java] - Removed value [org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$DefaultCrudMethodMetadata#6752dcc] for key [public abstract java.lang.Object org.springframework.data.repository.CrudRepository.save(java.lang.Object)] from thread [http-nio-8080-exec-2]
17:12:11,857 INFO [http-nio-8080-exec-2] [SlotConfigsController.java] - Transactional method finished
17:12:11,863 TRACE [http-nio-8080-exec-2] [TransactionSynchronizationManager.java] - Removed value [org.springframework.orm.jpa.EntityManagerHolder#4ecd9132] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#2210e466] from thread [http-nio-8080-exec-2]
And here is the docker DB log
17:12:11.871 UTC [555] test#test LOG: execute <unnamed>: update public.slot_configs set close_time=$1 where slot_config_id=$2
17:12:11.871 UTC [555] test#test DETAIL: parameters: $1 = '1630', $2 = 5
17:12:11.877 UTC [555] test#test LOG: execute S_2: COMMIT
At 17:12:11,857 we exited the Transactional CrudRepository.save method, but the real data insertion in the DB and transaction commit happens only at 17:12:11.871 - 17:12:11.877
I supposed, that when the #Transactional method will be finished, data should be already in the DB, but looks like this action is asynchronous.
I was also trying to create a Service between controller and repository and mark the save method in the service as #Transactional(propagation = Propagation.REQUIRES_NEW), but it doesn't change anything. There is still a lag between code transactions and actual transactions in the DB.
Why does it happen? And is it possible to say Spring to wait for the DB transaction commit before exiting the #Transactional method?

Related

Why is Ebean ORM throwing java.sql.SQLException: IJ031021: You cannot rollback during a managed transaction

I have a Jax-RS Rest service that uses Ebean to query the database. On any query I make this exception is thrown.
For example.
User currentUser = new QUser().where().id.eq(currentUserID)).findUnique();
Logs
ERROR [io.ebeaninternal.server.transaction.JdbcTransaction] (default task-10) Error when ending a query only transaction via ROLLBACK: java.sql.SQLException: IJ031021: You cannot rollback during a managed transaction
Now the query returns the appropriate user and doesn't interfere with the Jax-RS.
But I can't ignore the large code-smell
And the huge log that is created because it gets thrown on every query.
My Configuration
ServerConfig config = new ServerConfig();
config.setDataSource(ds);
config.setName("db");
config.setAutoCommitMode(false);
config.setDatabasePlatform(new PostgresPlatform());
config.setRegister(true);
config.setDefaultServer(true);
config.setTransactionRollbackOnChecked(true);
config.addPackage(User.class.getPackage().getName());
EbeanServer es = EbeanServerFactory.create(config);
When using ebean inside Java EE you need to configure the EbeanServer before it is used. A typical place to do it is in a #PostConstruct method in a #Startup #Singleton bean-managed transaction ejb. And you need to configure it to use the JTA transaction manager so it doesn't try to begin/commit the transactions on its own.
#Singleton
#Startup
#TransactionManagement(TransactionManagementType.BEAN)
public class AtStartup {
#Resource(mappedName = "java:jboss/datasources/EbeanTestDS")
private DataSource ds;
#SneakyThrows
#PostConstruct
public void startup() {
new MigrationRunner(new MigrationConfig()).run(ds); // begin/commits transaction for the migration...
ServerConfig config = new ServerConfig();
config.setDataSource(ds);
config.addPackage(Customer.class.getPackage().getName());
config.setUseJtaTransactionManager(true); // This is important !
config.setAutoCommitMode(false);
EbeanServerFactory.create(config);
}

Correct use of Hazelcast Transactional Map in an Spring Boot app

I am working on a proof of concept of Hazelcast Transactional Map. To accomplish this I am writing an Spring Boot app and using Atomikos as my JTA/XA implementation.
This app must update a transactional map and also update a database table by inserting a new row all within the same transaction.
I am using JPA / SpringData / Hibernate to work with the database.
So the app have a component (a JAVA class annotated with #Component) that have a method called agregar() (add in spanish). This method is annotated with #Transactional (org.springframework.transaction.annotation.Transactional)
The method must performe two task as a unit: first must update a TransactionalMap retrieved from Hazelcast instance and, second, must update a database table using a repository extended from JpaRepository (org.springframework.data.jpa.repository.JpaRepository)
This is the code I have written:
#Transactional
public void agregar() throws NotSupportedException, SystemException, IllegalStateException, RollbackException, SecurityException, HeuristicMixedException, HeuristicRollbackException, SQLException {
logger.info("AGRENADO AL MAPA ...");
HazelcastXAResource xaResource = hazelcastInstance.getXAResource();
UserTransactionManager tm = new UserTransactionManager();
tm.begin();
Transaction transaction = tm.getTransaction();
transaction.enlistResource(xaResource);
TransactionContext context = xaResource.getTransactionContext();
TransactionalMap<TaskKey, TaskQueue> mapTareasDiferidas = context.getMap("TAREAS-DIFERIDAS");
TaskKey taskKey = new TaskKey(1L);
TaskQueue taskQueue = mapTareasDiferidas.get(taskKey);
Integer numero = 4;
Task<Integer> taskFactorial = new TaskImplFactorial(numero);
taskQueue = new TaskQueue();
taskQueue.getQueue().add(taskFactorial);
mapTareasDiferidas.put(taskKey, taskQueue);
transaction.delistResource(xaResource, XAResource.TMSUCCESS);
tm.commit();
logger.info("AGRENADO A LA TABLA ...");
PaisEntity paisEntity = new PaisEntity(100, "ARGENTINA", 10);
paisRepository.save(paisEntity);
}
This code is working: if one of the tasks throw an exception then both are rolled back.
My questions are:
Is this code actually correct?
Why #Transactional is not taking care of commiting the changes in the map and I must explicitylly do it on my own?
The complete code of the project is available en Github: https://github.com/diegocairone/hazelcast-maps-poc
Thanks in advance
Finally i realized that i must inject the 'UserTransactionManager' object and take the transaction from it.
Also is necessary to use a JTA/XA implementation. I have chosen Atomikos and XA transactions must be enable in MS SQL Server.
The working example is available at Github https://github.com/diegocairone/hazelcast-maps-poc on branch atomikos-datasource-mssql
Starting with Hazelcast 3.7, you can get rid of the boilerplate code to begin, commit or rollback transactions by using HazelcastTransactionManager which is a PlatformTransactionManager implementation to be used with Spring Transaction API.
You can find example here.
Also, Hazelcast can participate in XA transaction with Atomikos. Here's a doc
Thank you
I have updated to Hazelcast 3.7.5 and added the following code to HazelcastConfig class.
#Configuration
public class HazelcastConfig {
...
#Bean
public HazelcastInstance getHazelcastInstance() {
....
}
#Bean
public HazelcastTransactionManager getTransactionManager() {
HazelcastTransactionManager transactionManager = new HazelcastTransactionManager(getHazelcastInstance());
return transactionManager;
}
#Bean
public ManagedTransactionalTaskContext getTransactionalContext() {
ManagedTransactionalTaskContext transactionalContext = new ManagedTransactionalTaskContext(getTransactionManager());
return transactionalContext;
}
When I run the app I get this exception:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
bean named 'transactionManager' available: No matching
PlatformTransactionManager bean found for qualifier
'transactionManager' - neither qualifier match nor bean name match!
The code is available at Github on a new branch: atomikos-datasource-mssql-hz37
Thanks in advance

Spring Service #Transactional doesn't rollback transaction Mybatis SqlSession

The goal is to rollback all/any transactions in case of failure. But this doesn't work as expected.
We use Spring MVC + JMS + Service + Mybatis. In the logs, the JMS is set to rollback, but the row is inserted and not rollback. Would like to know what I'm missing or doing wrong?
The #Transactional tag was added recently. So not sure if it works as expected.
Code:
Service Class:
#Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class DataExchangeLogic implements DataExchangeService {
private DataExchDao dataExchDao;
...
#Override
public void save(DataExch dataExch) throws ValidationException {
if (dataExch.getId() != null && dataExch.getId() > 0) {
this.dataExchDao.update(dataExch);
} else {
//LOGGER.debug("in insert::");
this.dataExchDao.create(dataExch);
//Empty exception throw to test rollback
throw new RuntimeException();
}
}
}
DAO:
public interface DataExchDaoMybatis
extends NotificationDao {
void create(DataExch dataExch);
}
Spring Context
<bean id="dataExchLogic" class="com.abc.service.logic.DataExchLogic">
<property name="dataExchDao" ref="dataExchDao" />
</bean>
EAR/WAR project Spring Context
<!-- Transaction Manager -->
<bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />
<tx:annotation-driven transaction-manager="transactionManager" />
Logs:
[31mWARN [0;39m [36mo.s.j.l.DefaultMessageListenerContainer[0;39m # Setup of JMS message listener invoker failed for destination 'queue://REQUEST?priority=1&timeToLive=500000' - trying to recover. Cause: Transaction rolled back because it has been marked as rollback-only
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:720)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:240)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1142)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1134)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1031)
at java.lang.Thread.run(Thread.java:745)
[34mINFO [0;39m [36mo.s.j.l.DefaultMessageListenerContainer[0;39m # Successfully refreshed JMS Connection
[39mDEBUG[0;39m [36mo.s.j.l.DefaultMessageListenerContainer[0;39m # Received message of type [class com.ibm.ws.sib.api.jms.impl.JmsTextMessageImpl] from consumer [com.ibm.ws.sib.api.jms.impl.JmsQueueReceiverImpl#6ca01c74] of transactional session [com.ibm.ws.sib.api.jms.impl.JmsQueueSessionImpl#3ac3b63]
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession#206ee277]
JDBC Connection [com.ibm.ws.rsadapter.jdbc.WSJdbcConnection#19b89f0c] will be managed by Spring
[39mDEBUG[0;39m [36mg.c.i.q.d.m.N.create!selectKey[0;39m # ==> Preparing: SELECT ID.NEXTVAL FROM DUAL
[39mDEBUG[0;39m [36mg.c.i.q.d.m.N.create!selectKey[0;39m # ==> Parameters:
[39mDEBUG[0;39m [36mg.c.i.q.d.m.N.create!selectKey[0;39m # <== Total: 1
[39mDEBUG[0;39m [36mg.c.i.q.d.m.N.create[0;39m # ==> Preparing: INSERT INTO TABLE ( COL1, COL2, COL N) VALUES ( ?, CURRENT_TIMESTAMP, ?, ?, ?, ?, ?, ?)
[39mDEBUG[0;39m [36mg.c.i.q.d.m.N.create[0;39m # ==> Parameters: 468(Integer), SYSTEM(String), 2017-03-01 00:00:00.0(Timestamp), 2017-03-16 00:00:00.0(Timestamp), true(Boolean), test 112(String), ALL(String)
[39mDEBUG[0;39m [36mg.c.i.q.d.m.N.create[0;39m # <== Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession#206ee277]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession#206ee277]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession#206ee277]
EDIT 1:
Controller code:
#ResourceMapping(value = "addNewDEURL")
public void addNewDE(#ModelAttribute(value = "dataObject") final DataExch dataExch,
final BindingResult bindingResult, final ResourceResponse response) {
if (!bindingResult.hasErrors()) {
try {
dataExchangeService.save(dataExch);
} catch (final ValidationException e) {
logger.error("A validation exception occurred.", e);
}
} else {
logger.error(bindingResult.getAllErrors().get(0)
.getDefaultMessage());
}
}
DAO changed:
public class DataExchDaoMybatis extends BaseDaoImpl implements DataExchDao {
public void create(DataExch dataExch) {
doSimpleInsert("insertDE", dataExch);
}
}
BaseDaoImpl:
public void doSimpleInsert(String queryId, Object o) {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert(queryId, o);
}
Please put transactionManager configuration and tx:annotation-driven into root spring context
Rule: Root context can see all the beans which Spring created. Child context(any Web Context) can see only its own beans.
In this particular case tx:annotation-driven looks for beans with #Transactional annotation in Web context. It cannot find any because you defined dataExchLogic in root context. That's why you didn't have any transactional behavior.
#EnableTransactionManagement and only looks for #Transactional on beans in the same application context they are defined in. This means that, if you put annotation driven configuration in a WebApplicationContext for a DispatcherServlet, it only checks for #Transactional beans in your controllers, and not your services. See Section 21.2, “The DispatcherServlet” for more information.
Solution implies to move tx:annotation-driven to the root context because Root Context can find any bean defined either in root or in any web context.
Quoting from spring documentation:
You can place the #Transactional annotation before an interface
definition, a method on an interface, a class definition, or a public
method on a class. However, the mere presence of the #Transactional
annotation is not enough to activate the transactional behavior. The
#Transactional annotation is simply metadata that can be consumed by
some runtime infrastructure that is #Transactional-aware and that can
use the metadata to configure the appropriate beans with transactional
behavior. In the preceding example, the
element switches on the transactional behavior.
Which means,
void create(DataExch dataExch);
should be
public void create(DataExch dataExch);
#Transactional annotation behavior is not exhibited if it is not applied on a public method.
EDIT:
Since my answer was downvoted, to support my answer and to shed some light on the transactional behavior when a Transactional annotated method calls a method without annotation, take a look at this:
#Transactional method calling another method without #Transactional anotation? specifically the answer by Arun P Johny
I think of two possibilities.
1) Your DAO class is starting a new transaction.
2) Your DAO class is not participating in the transaction.
I dont see any other reason why the data should be updated to the database. Can you add below property to log4j to see how many transactions are being started.
log4j.logger.org.springframework.transaction.interceptor = trace
Also syosut the below transaction status in Service and DAO method to see if the transaction is active.
TransactionSynchronizationManager.isActualTransactionActive()
Let us know what happens.

Spring Data Jpa MVC - data not inserting, but persists during Test

My problem is quite the other way round, most questions here are for test data not being inserted, mine persists in tests but not when called thru the controller.
I'm still new at this so may have made some silly mistakes. Any help is appreciated!
This is my setup.
Project 1: Business Logic Layer: Entities, Services, Repo (Spring Data), Oracle => bll.jar (Test saves, can see insert statements in log). Files: AppConfig, HibernateConfig, PersistenceConfig
Project 2: Spring MVC 4.3.3, Thymeleaf 3, import bll.jar, controller calls BLL Service to save. No insert statements in log, just select statements. Oracle sequence number being incremented. The returned object after save() shows the new object with new Id. No error. Deployed in JBoss Wildfly.
What I tried so far
Thinking it must be a commit or flush issue, added saveAndFlush() in repo and service. Works in BLL Test but when called from MVC it gives error No transaction is in progress.
Checked MVC save() and looked for bindingResult errors, there were none
Log seems to show transaction commit so don't know why it isn't persisting
Added #Transactional(propagation = Propagation.REQUIRED) above my controller save() following Data not inserted to db but no effect
Controller
#PostMapping(value="/create", params={"save"}) //
public String save(final Cat cat
, final BindingResult bindingResult, final ModelMap model){
if(bindingResult.hasErrors()){
logger.info(bindingResult.getAllErrors().toString());
return "cat/create";
}
Cat updatedCat = catService.save(cat); //saveAndFlush
model.clear();
return "redirect:/cat/create";
}
Edit 1
Note my controller does not have #Transaction, just my BLL Service
method
Also, my entity Cat has related entities but I omited for brevity
Service
#Transactional
public Cat save(Cat cat){
return catRepo.save(cat);
}
Relevant log
2017-02-27 08:52:22 DEBUG SQL:109 - select catdts0_.CAT_ID as
CAT_ID6_0_0_, .. from CAT_DT catdts0_ where
catdts0_.CAT_ID=? 2017-02-27 08:52:22 TRACE BasicBinder:81 - binding
parameter [1] as [NUMERIC] - [1] .. 2017-02-27 08:52:22 TRACE
BasicExtractor:78 - extracted value ([CAT_ID6_0_0_] : [NUMERIC]) - [1]
2017-02-27 08:52:22 TRACE BasicExtractor:78 - extracted value
([ID1_1_0_] : [NUMERIC]) - [1] 2017-02-27 08:52:22 DEBUG
EntityManagerFactoryUtils:435 - Closing JPA EntityManager 2017-02-27
08:52:22 DEBUG HibernateTransactionManager:759 - Initiating
transaction commit 2017-02-27 08:52:22 DEBUG
HibernateTransactionManager:580 - Committing Hibernate transaction on
Session
[SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=org.hibernate.engine.spi.ExecutableList#63cd240d
updates=org.hibernate.engine.spi.ExecutableList#6262ff06
deletions=org.hibernate.engine.spi.ExecutableList#72d1cb79
orphanRemovals=org.hibernate.engine.spi.ExecutableList#3ff23a08
collectionCreations=org.hibernate.engine.spi.ExecutableList#35158cb7
collectionRemovals=org.hibernate.engine.spi.ExecutableList#407acfdc
collectionUpdates=org.hibernate.engine.spi.ExecutableList#3c0c4ea9
collectionQueuedOps=org.hibernate.engine.spi.ExecutableList#1200015a
unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])]
2017-02-27 08:52:22 DEBUG DataSourceUtils:222 - Resetting read-only
flag of JDBC Connection [oracle.jdbc.driver.T4CConnection#1dfb6d07]
2017-02-27 08:52:22 DEBUG HibernateTransactionManager:669 - Closing
Hibernate Session
[SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=org.hibernate.engine.spi.ExecutableList#63cd240d
updates=org.hibernate.engine.spi.ExecutableList#6262ff06
deletions=org.hibernate.engine.spi.ExecutableList#72d1cb79
orphanRemovals=org.hibernate.engine.spi.ExecutableList#3ff23a08
collectionCreations=org.hibernate.engine.spi.ExecutableList#35158cb7
collectionRemovals=org.hibernate.engine.spi.ExecutableList#407acfdc
collectionUpdates=org.hibernate.engine.spi.ExecutableList#3c0c4ea9
collectionQueuedOps=org.hibernate.engine.spi.ExecutableList#1200015a
unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] after
transaction 2017-02-27 08:52:22 DEBUG DispatcherServlet:1251 -
Rendering view [org.thymeleaf.spring4.view.ThymeleafView#13f5fc54] in
DispatcherServlet with name 'appServlet' 2017-02-27 08:52:22 DEBUG
ReloadableResourceBundleMessageSource:440 - No properties file found
for [/resources/i18n/messages_en_GB] - neither plain properties nor
XML 2017-02-27 08:52:22 DEBUG
ReloadableResourceBundleMessageSource:410 - Re-caching properties for
filename [/resources/i18n/messages_en] - file hasn't been modified
2017-02-27 08:52:22 DEBUG DispatcherServlet:1000 - Successfully
completed request
If I missed any important info then let me know what to post, I'm still groping in the dark.
Answering my own question, with help from #Naros
Turns out my PersistenceConfig was messed up.
PersistenceConfig
public class PersistenceConfig {
...
#Bean
public PlatformTransactionManager transactionManager()
{
EntityManagerFactory factory = entityManagerFactory().getObject();
return new JpaTransactionManager(factory);
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(s);
return txManager;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory()
{
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(false); //was true
vendorAdapter.setShowSql(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dataSource());
factory.setJpaVendorAdapter(vendorAdapter);
factory.setJpaProperties(jpaProperties());
factory.setPackagesToScan("ae.tbits.atn.aiwacore.common.model");
return factory;
}
#Bean
public DataSource dataSource() {
...
return dataSource;
}
}
Had 2 transactionManager(), I suspect one was called in Test while the other in my web controller. Removed the below to solve the problem.
public HibernateTransactionManager transactionManager(SessionFactory s)

Not able to capture SessionDestroyed event in Spring Redis Session + Spring boot environment

I have a Spring Boot project with Spring Session backed by Redis. I am trying to capture sessionDestroyed event so that I can perform some clean up.
The code to capture the event is as below as per guidance I found elsewhere on Stack Overflow.
#Component
public class SessionEndedListener implements ApplicationListener<SessionDestroyedEvent> {
private final Logger LOGGER = LoggerFactory.getLogger(getClass());
#Override
public void onApplicationEvent(SessionDestroyedEvent event) {
LOGGER.info("Destroyed session: {}", event.getSessionId());
}
}
I have set up my Redis Session Configuration like so
#EnableRedisHttpSession(maxInactiveIntervalInSeconds = 120)
public class RedisSessionConfig {
}
I can see some logs from Spring Redis cleaning up expired sessions every minute as shown below
2016-07-21 11:07:00,026 ==== RedisSessionExpirationPolicy.java ==== thread: pool-4-thread-1 ==== DEBUG >
org.springframework.session.data.redis.RedisSessionExpirationPolicy.cleanExpiredSessions() => [] (line: 107)
Cleaning up sessions expiring at Thu Jul 21 11:07:00 EDT 2016
But the code that is meant to capture the SessionDestroyedEvent is never called.
What am I missing here?
Please note that I am testing this with a local Redis server where there is no problem in configuring key-space-events as Egx.
When I debugged through the code.
This statement
if(!body.startsWith("spring:session:sessions:")) {
return;
}
in the class
org.springframework.session.data.redis.SessionMessageListener returns prematurely before getting a chance to publish the event
because the variable body has a value
\xac\xed\x00\x05t\x00<spring:session:sessions:2392443d-62a9-4f8c-81f0-c0bb446eb16f
I am using spring-session 1.0.2.RELEASE. Was there a bug that was fixed?

Resources