/**
* @author Incheol Jung
*/
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Owner {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToMany(mappedBy = "owner", fetch = FetchType.EAGER)
private Set<Cat> cats = new LinkedHashSet<>();
...
}
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Cat {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToOne
private Owner owner;
public Cat(String name) {
this.name = name;
}
}
@Test
void exampleTest() {
Set<Cat> cats = new LinkedHashSet<>();
for(int i = 0; i < 10; i++){ // Set당 Cat 객체 10개 추가
cats.add(new Cat("cat" + i));
}
catRepository.saveAll(cats);
List<Owner> owners = new ArrayList<>();
for(int i = 0; i < 10; i++){ // 매 Owner에 Cat 10개짜리 Set 추가
Owner owner = new Owner("owner" + i);
owner.setCats(cats);
owners.add(owner);
}
ownerRepository.saveAll(owners);
entityManager.clear();
System.out.println("-------------------------------------------------------------------------------");
List<Owner> everyOwners = ownerRepository.findAll();
assertFalse(everyOwners.isEmpty());
}
FetchType.LAZY로 설정
public class Owner {
@OneToMany(mappedBy = "owner", fetch = FetchType.LAZY)
private Set<Cat> cats = new LinkedHashSet<>();
...
}
List<Owner> everyOwners = ownerRepository.findAll();
// 이 경우 똑같이 N개의 쿼리가 나가버린다.
List<String> catNames = everyOwners.stream()
.flatMap(it -> it.getCats().stream().map(cat -> cat.getName()))
.collect(Collectors.toList());
assertFalse(catNames.isEmpty());
Fetch join 사용
@Query("select o from Owner o join fetch o.cats")
List<Owner> findAllJoinFetch();
EntityGraph 사용
@EntityGraph(attributePaths = "cats")
@Query("select o from Owner o")
List<Owner> findAllEntityGraph();
@Fetch(FetchMode.SUBSELECT) 사용
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Owner {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@Fetch(FetchMode.SUBSELECT)
@OneToMany(mappedBy = "owner", fetch = FetchType.EAGER)
private Set<Cat> cats = new LinkedHashSet<>();
}
@BatchSize 사용
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Owner {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@BatchSize(size=5)
@OneToMany(mappedBy = "owner", fetch = FetchType.EAGER)
private Set<Cat> cats = new LinkedHashSet<>();
}
<aside> ➡️ <property name="hibernate.default_batch_fetch_size" value="5" />
</aside>
QueryBuilder를 사용한다.