gpt4 book ai didi

java - 如何解决 Spring Data JPA 中的 LazyInitializationException?

转载 作者:IT老高 更新时间:2023-10-28 13:52:45 25 4
gpt4 key购买 nike

我有两个具有一对多关系的类。当我尝试访问延迟加载的集合时,我得到 LazyInitializationException。我已经在网上搜索了一段时间,现在我知道我得到了异常,因为用于加载包含集合的类的 session 已关闭。但是,我没有找到解决方案(或者至少我不理解它们)。基本上我有这些类(class):

用户

@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;
}

}

用户存储库

public interface UserRepository extends JpaRepository<User, Long> {}

用户服务

@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();
}

}

工作

@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> {}

工作服务

@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;
}
}
}
}

}

应用

@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(); // Generates some users and stores them in the db
jobService.addJobsForUsers(userService.getAllUsers()); // Generates some jobs for the users

final User random = userService.getRandomUser(); // Picks a random user

System.out.println(random.getCreatedJobs());
}

}

我经常读到 session 必须绑定(bind)到当前线程,但我不知道如何使用 Spring 的基于注释的配置来做到这一点。有人能指出我该怎么做吗?

附:我想使用延迟加载,因此无法使用急切加载。

最佳答案

基本上,您需要在事务中获取惰性数据。如果您的服务类是 @Transactional,那么当您在其中时,一切都应该没问题。一旦你离开服务类,如果你尝试 get 惰性集合,你会得到那个异常,它在你的 main() 方法中,行 System.out.println(random.getCreatedJobs());.

现在,归结为您的服务方法需要返回什么。如果 userService.getRandomUser() 预计会返回一个已初始化作业的用户,以便您可以操作它们,那么获取它是该方法的责任。使用 Hibernate 最简单的方法是调用 Hibernate.initialize(user.getCreatedJobs())

关于java - 如何解决 Spring Data JPA 中的 LazyInitializationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26507446/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com