Devo classi che hanno una relazione uno-a-molti. Quando provo ad accedere alla collezione caricata pigramente ottengo il LazyInitializationException
. Cerco il web da un po 'ora e ora so che ottengo l'eccezione perché la sessione utilizzata per caricare la classe che detiene la collezione è chiusa. Tuttavia non ho trovato una soluzione (o almeno non li ho capiti). Fondamentalmente ho quelle classi:Come risolvere LazyInitializationException in Spring Data JPA?
utente
@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> {}
UserService
@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();
}
}
lavoro
@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;
}
}
}
}
}
App
Ho letto spesso che la sessione deve essere associata al thread corrente, ma non so come farlo con le configurazioni basate su annotazione di Spring. Qualcuno potrebbe indicarmi come farlo?
P.S. Voglio usare il caricamento lazy, quindi il carico impaziente non è un'opzione.
È possibile incollare il codice per i servizi che caricano le entità? – Smutje