Uploaded image for project: 'Causeway'
  1. Causeway
  2. CAUSEWAY-3687

[Validation] Disallow @Transactional within @DomainService(nature=VIEW)

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Major
    • Resolution: Resolved
    • 2.0.0-RC4
    • 2.0.0
    • Viewer Wicket
    • None

    Description

      package com.kn.lx.domain;
      
      import com.kn.lx.util.Constants;
      import com.kn.lx.config.Properties;
      import com.kn.lx.input.elastic.QueryResultItemTO;
      import com.kn.lx.input.elastic.QueryService;
      import com.kn.lx.input.elastic.pr.PrQuery;
      import lombok.NonNull;
      import lombok.RequiredArgsConstructor;
      import org.apache.causeway.applib.annotation.Action;
      import org.apache.causeway.applib.annotation.ActionLayout;
      import org.apache.causeway.applib.annotation.DomainService;
      import org.apache.causeway.applib.annotation.NatureOfService;
      import org.apache.causeway.applib.annotation.Programmatic;
      import org.apache.causeway.applib.annotation.SemanticsOf;
      import org.springframework.transaction.annotation.Transactional;
      
      import javax.inject.Inject;
      import javax.inject.Named;
      import java.lang.reflect.InvocationTargetException;
      import java.time.LocalDateTime;
      import java.util.List;
      import java.util.Optional;
      
      @Named("lx.Tasks")
      @DomainService(nature = NatureOfService.VIEW)
      @RequiredArgsConstructor(onConstructor_ = {@Inject})
      public class Tasks {
          private final TaskRepository taskRepository;
          private final QueryService queryService;
          private final Executions executions;
          private final Properties properties;
      
          @Programmatic
          public Task create(String className) {
              final Task obj = new Task();
              obj.setQueryClassName(className);
              obj.setCronExpression(Constants.INSTANCE.getEVERY_FIVE_MINUTES());
              obj.setActive(true);
              taskRepository.saveAndFlush(obj);
              return obj;
          }
      
          @ActionLayout(sequence = "1")
          public List<Task> listAll() {
              return taskRepository.findAll();
          }
      
          public void init() {
              createIfAbsent(PrQuery.class.getCanonicalName());
          }
      
          @ActionLayout(sequence = "2")
          public void createIfAbsent(final String name) {
              final Task obj = taskRepository.findByQueryClassName(name);
              if (null == obj) {
                  create(name);
              }
          }
      
          @Action(semantics = SemanticsOf.SAFE)
          @ActionLayout(sequence = "3", cssClassFa = "trash")
          public void delete(Task task) {
              taskRepository.delete(task);
          }
      
          List<QueryResultItemTO> executeQuery(PrQuery query) {
              final Integer chunkSize = properties.getInteger(Constants.INSTANCE.getELASTIC_QUERY_CHUNK_SIZE());
              query.setMaxNumberOfHits(chunkSize);
              String latestTimeStamp = properties.getString(Constants.INSTANCE.getEND_TIME_STAMP());
              if (latestTimeStamp.isEmpty()) {
                  latestTimeStamp = properties.getString(Constants.INSTANCE.getSTART_TIME_STAMP());
              }
              return queryService.searchBy(query, latestTimeStamp);
          }
      
          @NonNull PrQuery createForClass(String queryClassName) {
              try {
                  return (PrQuery) Class.forName(queryClassName).getDeclaredConstructor().newInstance();
              } catch (InstantiationException |
                       IllegalAccessException |
                       ClassNotFoundException |
                       InvocationTargetException |
                       NoSuchMethodException e) {
                  throw new RuntimeException(e);
              }
          }
      
          @Transactional
          public Task execute(Task argTask) {
              final Task task = update(argTask);
              if (task.isActive()) {
                  final PrQuery query = createForClass(task.getQueryClassName());
                  final List<QueryResultItemTO> queryResultList = executeQuery(query);
                  final Execution e = executions.create(task, queryResultList);
                  e.setEndedAt(LocalDateTime.now());
                  e.setHits((long) queryResultList.size());
                  task.getExecutionList().add(e);
                  taskRepository.saveAndFlush(task);
                  executions.sendMessagesFor(e);
                  return task;
              }
              return null;
          }
      
          /**
           * It seems argTask is out of sync when it reaches this point.
           * Read it again.
           *
           * @param argTask Task to be synced
           * @return Task, synced with DB
           */
          private Task update(Task argTask) {
              final Optional<? extends Task> optionalTask = taskRepository.findById(argTask.getId());
              if (optionalTask.isPresent()) {
                  return optionalTask.get();
              } else {
                  throw new RuntimeException("Task not found");
              }
          }
      
      }
      
      

      Attachments

        1. screenshot-1.png
          37 kB
          Jörg Rade

        Activity

          People

            hobrom Andi Huber
            joerg.rade Jörg Rade
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: