@Transactional
@Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must not be null");
if (entityInformation.isNew(entity)) {
em.persist(entity); // 비영속 -> 영속
return entity;
} else {
return em.merge(entity); // 준영속 -> 영속
}
}
@Test
void saveAndCompare() {
Crew pepper = new Crew("페퍼");
Crew crew = crewRepository.save(pepper);
assertThat(crew).isEqualTo(pepper);
}
@Test
void find() {
Crew crew = crewRepository.save(new Crew("페퍼"));
Optional<Crew> findCrew = crewRepository.findById(crew.getId());
assertThat(findCrew).hasValue(crew);
}
@Test
void removed() {
Crew pepper = crewRepository.save(new Crew("페퍼"));
Long pepperId = pepper.getId();
crewRepository.deletedById(pepperId);
assertThat(crewRepository.findById(pepperId));
}
@Test
void removed() {
Crew pepper = crewRepository.save(new Crew("페퍼"));
Long pepperId = pepper.getId();
crewRepository.deletedById(pepperId);
// 예외 발생 : 값은 빼올 수 없다
assertThat(crewRepository.findById(pepperId))
.isPresent();
}
deleteAll : 내부적으로 findAll 먼저 수행
해결책 1 : deleteAll 후 바로 flush 직접 호출
헤결책 2 : JPQL 쿼리 사용
해결책 3 : 트랜잭션 커밋
flush는 언제 발생할까?
@Service
@RequiredArgsConstructor
public class CrewService {
private final CrewRepository crewRepository;
public void updateAllAge() {
List<Crew> crews = crewRepository.findAll();
for (Crew crew : crews) {
crew.updateAge();
}
}
}
public interface CrewRepository extends JpaRepository<Crew, Long> {
@Modifying
@Query("update Crew c set c.age = c.age + 1")
int increaseAllAge();
}
@Test
void increaseAgeOfEveryone() {
Crew 마루 = crewRepository.save(new Crew("마루", 24));
Crew 잉 = crewRepository.save(new Crew("잉", 20));
Crew 페퍼 = crewRepository.save(new Crew("페퍼", 26));
Crew 록바 = crewRepository.save(new Crew("록바", 26));
crewRopository.increaseAllAge();
System.out.println("count = " + count);
assertAll(
() -> assertThat(마루.getAge()).isEqualTo(25),
() -> assertThat(잉.getAge()).isEqualTo(21),
() -> assertThat(페퍼.getAge()).isEqualTo(27),
() -> assertThat(록바.getAge()).isEqualTo(27)
);
}
@Service
@RequiredArgsConstructor
public class CrewService {
private final CrewRepository crewRepository;
public void updateAllAge() {
List<Crew> crews = crewRepository.findAll();
for(Crew crew : crews) {
crew.updateAge();
}
}
@Test
void increaseAgeOfEveryone() {
Crew 마루 = crewRepository.save(new Crew("마루", 24));
Crew 잉 = crewRepository.save(new Crew("잉", 20));
Crew 페퍼 = crewRepository.save(new Crew("페퍼", 26));
Crew 록바 = crewRepository.save(new Crew("록바", 26));
crewRopository.increaseAllAge();
System.out.println("count = " + count);
entityManager.flush();
entityManager.clear();
assertAll(
() -> assertThat(crewRepository.findById(마루.getId()).get().getAge()).isEqualTo(25),
() -> assertThat(crewRepository.findById(잉.getId()).get().getAge()).isEqualTo(21),
() -> assertThat(crewRepository.findById(페퍼.getId()).get().getAge()).isEqualTo(27),
() -> assertThat(crewRepository.findById(록바.getId()).get().getAge()).isEqualTo(27)
);
}
public interface CrewRepository extends JpaRepository<Crew, Long> {
@Modifying(clearAutomatically = true)
@Query("update Crew c set c.age = c.age + 1")
int increaseAllAge();
}
@Test
@DisplayName("Test")
void t001() throws Exception {
Crew 마루 = crewRepository.save(new Crew("마루", 24));
Crew 잉 = crewRepository.save(new Crew("잉", 20));
Crew 페퍼 = crewRepository.save(new Crew("페퍼", 26));
Crew 록바 = crewRepository.save(new Crew("록바", 26));
int count = crewRepository.increaseAllAge();
System.out.println("count = " + count);
assertAll(
() -> assertThat(crewRepository.findById(마루.getId()).get().getAge()).isEqualTo(25),
() -> assertThat(crewRepository.findById(잉.getId()).get().getAge()).isEqualTo(21),
() -> assertThat(crewRepository.findById(페퍼.getId()).get().getAge()).isEqualTo(27),
() -> assertThat(crewRepository.findById(록바.getId()).get().getAge()).isEqualTo(27)
);
}
getClass()
부분을 없애 class가 같다는 부분을 없애서 override 하는 것이 좋음