I have implemented an MQTT event listener like this:
@Service
@Slf4j
@RequiredArgsConstructor
public class SoilHumidityEventListener {
  private final MqttClient mqttClient;
  private final ObjectMapper objectMapper;
  private final PlantService plantService;
  @Value("${mqtt.soil_humidity_topic}")
  private String soilHumidityTopic;
  @Transactional
  public void subscribe() throws MqttException {
    mqttClient.subscribe(soilHumidityTopic, this::messageArrived);
  }
  @Transactional
  public void messageArrived(String topic, MqttMessage message) {
    try {
      SoilHumidityDto soilHumidityDto =
          objectMapper.readValue(message.toString(), SoilHumidityDto.class);
      Plant plant = plantService.findById(soilHumidityDto.getPlantId());
      SoilHumidity soilHumidity = SoilHumidity.fromDto(soilHumidityDto);
      soilHumidity.setPlant(plant);
      plant.getSoilHumidityList().add(soilHumidity);
      plantService.save(plant);
    } catch (Exception e) {
      log.error("Error parsing and saving soil humidity message: {}", e.getMessage());
    }
  }
}
The method plantService.findById(...) is also marked with @Transactional. the subscribe method in SoilHumidityEventListener is called in another service as bellow:
@Service
@RequiredArgsConstructor
@Slf4j
public class EventSubscriberService {
  private final SoilHumidityEventListener soilHumidityEventListener; 
  @PostConstruct
  @Transactional
  public void initialize() {
    try {
      soilHumidityEventListener.subscribe();      
    } catch (MqttException e) {
      log.error(e.getMessage());     
    }
  }
}
The problem is that there is no active transaction in the messageArrived() method. As a result I get a LazyInitializationException when trying to update the soilHumidityList of the plant object. The quick fix to this problem is to load the soilHumidityList eagerly. But I want to avoid this. Is there a way to keep the transaction open when handling MQTT messages?
