ste*_*oss 17 java spring hibernate
我必须拥有一对多关系的类.当我尝试访问延迟加载的集合时,我得到了LazyInitializationException.我现在在网上搜索了一段时间,现在我知道我得到了异常,因为用于加载保存集合的类的会话已关闭.但是我没有找到解决方案(或者至少我不理解它们).基本上我有这些课程:
用户
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
UserRepository
public interface UserRepository extends JpaRepository<User, Long> {}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
工作
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
JobRepository
public interface JobRepository extends JpaRepository<Job, Long> {}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
应用
@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());
}
}
Run Code Online (Sandbox Code Playgroud)
我经常读到会话必须绑定到当前线程,但我不知道如何使用Spring的基于注释的配置来完成此操作.有人可以指出我该怎么做?
PS我想使用延迟加载,因此急切加载是没有选择的.
Pre*_*ric 17
基本上,您需要在事务内部获取延迟数据.如果您的服务类是@Transactional,那么当您在其中时,一切都应该没问题.一旦你离开服务类,如果你尝试get了懒惰的集合,你将得到该异常,这在你的main()方法行中System.out.println(random.getCreatedJobs());.
现在,它归结为您的服务方法需要返回的内容.如果userService.getRandomUser()预期返回一个初始化了作业的用户,以便你可以操作它们,那么该方法就有责任获取它.使用Hibernate最简单的方法就是调用Hibernate.initialize(user.getCreatedJobs()).
考虑使用JPA 2.1和实体图:
延迟加载通常是 JPA 2.0 的一个问题。您必须在实体 FetchType.LAZY 或 FetchType.EAGER 上定义,并确保在事务中初始化关系。
这可以通过以下方式完成:
这两种方法都远非完美,JPA 2.1 实体图是更好的解决方案:
Bet*_*ide -2
改变
@OneToMany(mappedBy = "creator")
private Set<Job> createdJobs = new HashSet<>();
Run Code Online (Sandbox Code Playgroud)
到
@OneToMany(fetch = FetchType.EAGER, mappedBy = "creator")
private Set<Job> createdJobs = new HashSet<>();
Run Code Online (Sandbox Code Playgroud)
或者在你的服务中使用 Hibernate.initialize ,它具有相同的效果。
| 归档时间: |
|
| 查看次数: |
18676 次 |
| 最近记录: |