0

To access two different tables in the same database, I use two dedicated CrudRepositories:

public interface ProjectRepository extends CrudRepository<Project, String> {
   public Project findByCode(ProjectCode code);     
}

public interface ProjectEventRepository extends CrudRepository<ProjectEventDo, String> {}

In my service class, I need to write to both of them in the same transaction:

@Transactional
public void deleteProject( String code) throws NoSuchCodedItemException {

    ProjectCode pCode= new ProjectCode(code);
    Project project = this.projectRepo.findByCode(pCode);
    if( project != null ) {
        this.projectRepo.save(project);
        project.getEvents().forEach(event -> {
            this.eventRepo.save(ProjectEventDo.of(event));
        });
    }

    throw new NoSuchCodedItemException(code);
}

What I would like to do instead, is factor this out to a common method of the service class like so:

@Transactional
public void persist(Project project) {
    this.projectRepo.save(project);
    project.getEvents().forEach(event -> {
        this.eventRepo.save(ProjectEventDo.of(event));
    });
}


public void deleteProject( String code) throws NoSuchCodedItemException {

    ProjectCode pCode= new ProjectCode(code);
    Project project = this.projectRepo.findByCode(pCode);
    if( project != null ) {
        this.persist(project);
    }

    throw new NoSuchCodedItemException(code);
}

This is along the lines of this answer to same kind of problem. However, it throws this warning:

@Transactional self-invocation (in effect, a method within the target object calling
another method of the target object) does not lead to an actual transaction at runtime

In this accepted answer, the point is made to avoid self-invoking public methods, and indeed it is public only to please the @Transactional annotation, which requires it.

Is there a way to do the refactoring?

onouv
  • 528
  • 1
  • 5
  • 12

1 Answers1

0

It appears both methods need the @Transactional, to avoid the warning. Duhh. Should have seen this.

Still leaves us with the itch of a purely internal method (persist) made public only for the JPA mechanism.

onouv
  • 528
  • 1
  • 5
  • 12