Spring jpa save call to update a custom entity not working when using from a javadeligate implementation

Hi,
I’m using flowable cmmn with a spring boot application. In my javadeligate implementation, I try to update a custom entity using spring jpa repository caseEscalationRepository.save(caseEscalationDao), but this didn’t work. I don’t see any error message. In same javadeligate implementation I have used escalationRepository.findAllById(l1EscalationsIds), this returns results from custom table. I tried to print all the sql statements using spring.jpa.show-sql=true, I saw only the select queries. I don’t know why insert queries not working.

How does your delegate look like? Is it with an injected repository bean?

My Deligate is:

@Service
public class FirstLevelEscalationServiceImpl implements PlanItemJavaDelegate {
private static final Logger LOG = LoggerFactory.getLogger(FirstLevelEscalationServiceImpl.class);
private final NotificationService notificationService;
private final FrontendPagePathsProperties frontendPagePathsProperties;
private final MessagesUtil messagesUtil;
private final CaseEscalationRepository caseEscalationRepository;
private final SystemNotificationService systemNotificationService;
private final EscalationRepository escalationRepository;
private final CaseRepository caseRepository;
private final GroupRepository groupRepository;

/**
 * Constructor to initialize obj.
 * @param notificationService notification service
 * @param frontendPagePathsProperties frontend properties
 * @param messagesUtil for i18n
 * @param caseEscalationRepository jpa repository of CaseEscalationDao
 * @param systemNotificationService system notification
 * @param escalationRepository jpa repository of EscalationDao
 * @param caseRepository jpa repository of CaseDao
 */
public FirstLevelEscalationServiceImpl(NotificationService notificationService,
                                       FrontendPagePathsProperties frontendPagePathsProperties, MessagesUtil messagesUtil,
                                       CaseEscalationRepository caseEscalationRepository,
                                       SystemNotificationService systemNotificationService,
                                       EscalationRepository escalationRepository, CaseRepository caseRepository,
                                       GroupRepository groupRepository) {
    this.notificationService = notificationService;
    this.frontendPagePathsProperties = frontendPagePathsProperties;
    this.messagesUtil = messagesUtil;
    this.caseEscalationRepository = caseEscalationRepository;
    this.systemNotificationService = systemNotificationService;
    this.escalationRepository = escalationRepository;
    this.caseRepository = caseRepository;
    this.groupRepository = groupRepository;
}

@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void execute(DelegatePlanItemInstance delegatePlanItemInstance) {
    LOG.info("this is case l1 escalation service task class");
    CaseDao caseDao = null;//caseRepository.findByCaseInstanceId(delegatePlanItemInstance.getCaseInstanceId());
    Object isL1Escalation =  delegatePlanItemInstance.getVariable("isL1Escalation");
    try {
        if (isL1Escalation != null && (boolean)isL1Escalation){
            escalateAtFirstLevel(delegatePlanItemInstance, caseDao);
        }
    } catch (NotificationServiceException | InterruptedException e) {
        LOG.error("Error occurred while sending escalation notification to users", e);
        //retry escalation
    }
}

private void escalateAtFirstLevel(DelegatePlanItemInstance delegatePlanItemInstance, CaseDao caseDao)
        throws NotificationServiceException, InterruptedException {
    LOG.info("inside escalateAtFirstLevel method");
    List<Long> l1EscalationsIds = (List<Long>) delegatePlanItemInstance.getVariable("l1EscalationsIds");
    List<EscalationDao> escalationDaos = escalationRepository.findAllById(l1EscalationsIds);
    List<CaseEscalationDao> caseEscalationDaos = new ArrayList<>();
    for (EscalationDao escalationDao : escalationDaos){      
        CaseEscalationDao caseEscalationDao = new CaseEscalationDao(caseDao, escalationDao, true,
                LocalDateTime.now(), false, null);
        caseEscalationDaos.add(caseEscalationDao);
    }

  //update case_escalation table
    caseEscalationRepository.saveAll(caseEscalationDaos);       
}}

and I inject all the dependencies using constructor.
Beans are annotated with @Repository

In deligate, the get call to custom table escalationRepository.findAllById(l1EscalationsIds) is working fine.
But the call to insert records caseEscalationRepository.saveAll(caseEscalationDaos); is not working.

Hi @joram,
I have shared the delegate details above. Do you see any issue in this?

From a quick glance, the delegate looks ok. The @Transactional can be removed, any delegate part of a case instance is executed within a transaction. Can you remove it?

But it could be related to how the datasource and transactions are configured. How are you running this? How did you set up the CMMN engine and its datasource/transactions? Or if using Spring Boot, which starters are you using?

@joram: Thanks for your reply.
I use cmmn engine with spring boot and the starter used is org.flowable:flowable-spring-boot-starter-cmmn:6.5.0.
Case instance is started by calling the method from my service class.
private CaseInstance startCmmnCase(String caseDefinitionKey, Map<String, Object> caseVariables){
return cmmnRuntimeService.createCaseInstanceBuilder()
.caseDefinitionKey(caseDefinitionKey)
.variables(caseVariables)
.start();
}

…and I have a task executor configured for cmmn

@Configuration
public class CmmnTaskExecutorConfig {

/**
 * Method to configure a bean of SyncTaskExecutor for cmmn engine.
 * @return TaskExecutor
 */
@Cmmn
@Bean
public TaskExecutor cmmnTaskExecutor() {
    return new SyncTaskExecutor();
}

}

The datasource and transactions are spring boot default ones. I haven’t explicitly configured it.