2

How can I setup my Thread class to be able to access the session for which the parent class has access to?

Currently the parent class is using SomeObject which has multiple Set's of Objects. These objects are required to be used by the DeviceRunner which is extending Thread.

This application is using Spring Boot/Spring Data JPA/Hibernate.

Update

Is it possible to @Autowire the repository as I would for a @Controller? The @Autowired repository as shown below returns null.

Setting up @Transactional has allowed me to process the SomeObject's objects but I am unable to get the Repository to Autowire so I can create/save?

Thank you

Code DeviceRunner extending Thread:

@Transactional(propagation=Propagation.REQUIRED)
public class DeviceRunner extends Thread {

    @Autowired
    public TestRunRepository repository;

    public SomeObject object;        

    private .....

    public DeviceRunner(args.... ) {
        // set private variables
    }

    public void run() {
        // do stuff
    }

    synchronized ....

}

Code SomeObject

@Data
@Entity
@Table(name = "test_run")
public class SomeObject {

  @ManyToMany(fetch = FetchType.LAZY)
  private Set<OtherObjects> otherObjects;

}

TestRunRepository

@Repository
@Transactional
public interface TestRunRepository extends PagingAndSortingRepository<TestRun, Long> {

}

Rest Controller which creates the thread

@Transactional(propagation=Propagation.REQUIRED)
 @RestController
public class HomeController {

 @Autowired
 public TestRunRepository repository;
  ....
  @Transactional
  private void runTestRunOnDevice(TestRun testRun) {


      DeviceRunner deviceRunner = new DeviceRunner(testRun);
      deviceRunner.start();
      while (deviceRunner.isAlive());
  }
}
2
  • Do you need to modify SomeObject from the thread or just read it? Commented Jul 27, 2016 at 7:31
  • Are you sure youre not missing @Transactional(readOnly = true) in calling method? Commented Jul 27, 2016 at 7:57

2 Answers 2

1

You can use transaction with propagation as Required which is the default one. @Transactional(Propagation.REQUIRED)

Sign up to request clarification or add additional context in comments.

1 Comment

When setting up Transactional(Propogation.REQUIRED) does this need to be done on This looks to be working to allow me to access objects from SomeObject but the Repositories are not autowiring correctly so I have no way to access them in the thread. I have updated my code above
1

I would add @Autowired EntityManager or Session to your Repository class. It works. Spring Data injects a proxy that yields the actual EntityManager/Session, depending on the transaction context (i.e. depending on the currently executing thread that calls it).

2 Comments

Setting up Autowired as shown above did not allow the repository to be wired to the class. Do I have to do this differently? Currently I am passing it in as part of the constructor but would prefer to have it autowired.
Either annotate a constructor like '@Autowired Repository(EntityManager em)' or setter like '@Autowired void setEntityManager(EntityManager em)' or field (less recommended from testability point of view). All 3 ways should work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.