I have one-to-many classes. When I try to access a lazily loaded collection, I get a LazyInitializationException . I have been searching the Internet for a while, and now I know that I am getting an exception because the session that was used to load the class containing the collection is closed. However, I did not find a solution (or at least did not understand them). I mainly have these classes:
User
@Entity @Table(name = "user") public class User { @Id @GeneratedValue @Column(name = "id") private long id; @OneToMany(mappedBy = "creator") private Set<Job> createdJobs = new HashSet<>(); public long getId() { return id; } public void setId(final long id) { this.id = id; } public Set<Job> getCreatedJobs() { return createdJobs; } public void setCreatedJobs(final Set<Job> createdJobs) { this.createdJobs = createdJobs; } }
UserRepository
public interface UserRepository extends JpaRepository<User, Long> {}
User service
@Service @Transactional public class UserService { @Autowired private UserRepository repository; boolean usersAvailable = false; public void addSomeUsers() { for (int i = 1; i < 101; i++) { final User user = new User(); repository.save(user); } usersAvailable = true; } public User getRandomUser() { final Random rand = new Random(); if (!usersAvailable) { addSomeUsers(); } return repository.findOne(rand.nextInt(100) + 1L); } public List<User> getAllUsers() { return repository.findAll(); } }
Job
@Entity @Table(name = "job") @Inheritance @DiscriminatorColumn(name = "job_type", discriminatorType = DiscriminatorType.STRING) public abstract class Job { @Id @GeneratedValue @Column(name = "id") private long id; @ManyToOne @JoinColumn(name = "user_id", nullable = false) private User creator; public long getId() { return id; } public void setId(final long id) { this.id = id; } public User getCreator() { return creator; } public void setCreator(final User creator) { this.creator = creator; } }
Jobrepository
public interface JobRepository extends JpaRepository<Job, Long> {}
JobService
@Service @Transactional public class JobService { @Autowired private JobRepository repository; public void addJob(final Job job) { repository.save(job); } public List<Job> getJobs() { return repository.findAll(); } public void addJobsForUsers(final List<User> users) { final Random rand = new Random(); for (final User user : users) { for (int i = 0; i < 20; i++) { switch (rand.nextInt(2)) { case 0: addJob(new HelloWorldJob(user)); break; default: addJob(new GoodbyeWorldJob(user)); break; } } } } }
applications
@Configuration @EnableAutoConfiguration @ComponentScan public class App { public static void main(final String[] args) { final ConfigurableApplicationContext context = SpringApplication.run(App.class); final UserService userService = context.getBean(UserService.class); final JobService jobService = context.getBean(JobService.class); userService.addSomeUsers();
I often read that the session should be tied to the current thread, but I donβt know how to do this using Spring annotation-based configurations. Can someone tell me how to do this?
PS I want to use lazy loading, so downloading is not an option.