From 5deef0c79d82ead3822897820e461f936d9a027b Mon Sep 17 00:00:00 2001 From: KWY Date: Tue, 12 Dec 2023 18:55:39 +0900 Subject: [PATCH 1/7] =?UTF-8?q?#240=20[chore]=20querydsl=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 83 ++++++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/build.gradle b/build.gradle index 4242c37c..fc8fca81 100644 --- a/build.gradle +++ b/build.gradle @@ -1,58 +1,65 @@ plugins { - id 'java' - id 'org.springframework.boot' version '2.7.13' - id 'io.spring.dependency-management' version '1.0.15.RELEASE' + id 'java' + id 'org.springframework.boot' version '2.7.13' + id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'com.asap' version = '0.0.1-SNAPSHOT' java { - sourceCompatibility = '11' + sourceCompatibility = '11' } configurations { - compileOnly { - extendsFrom annotationProcessor - } + compileOnly { + extendsFrom annotationProcessor + } } repositories { - mavenCentral() + mavenCentral() } dependencies { - implementation 'org.springframework.boot:spring-boot-starter-actuator' - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-aop' - implementation 'org.springframework.security:spring-security-crypto:5.7.9' - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - - // VALIDATION - implementation 'org.springframework.boot:spring-boot-starter-validation' - - // JPA & Database - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'mysql:mysql-connector-java:8.0.32' - - // SWAGGER - implementation 'org.springdoc:springdoc-openapi-ui:1.7.0' - - // Jwt Token - implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.2' - implementation group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.2' - implementation group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.2' - - // Slack Webhook - implementation 'com.slack.api:slack-api-client:1.28.0' - implementation 'com.google.code.gson:gson:2.10.1' - implementation 'com.squareup.okhttp3:okhttp:4.10.0' - implementation 'com.slack.api:slack-app-backend:1.28.0' - implementation 'com.slack.api:slack-api-model:1.28.0' + // == 스프링 부트 3.0 미만 == + implementation 'com.querydsl:querydsl-jpa' + annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa" + + annotationProcessor "jakarta.annotation:jakarta.annotation-api" + annotationProcessor "jakarta.persistence:jakarta.persistence-api" + + implementation 'org.springframework.boot:spring-boot-starter-actuator' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-aop' + implementation 'org.springframework.security:spring-security-crypto:5.7.9' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + + // VALIDATION + implementation 'org.springframework.boot:spring-boot-starter-validation' + + // JPA & Database + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'mysql:mysql-connector-java:8.0.32' + + // SWAGGER + implementation 'org.springdoc:springdoc-openapi-ui:1.7.0' + + // Jwt Token + implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.2' + implementation group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.2' + implementation group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.2' + + // Slack Webhook + implementation 'com.slack.api:slack-api-client:1.28.0' + implementation 'com.google.code.gson:gson:2.10.1' + implementation 'com.squareup.okhttp3:okhttp:4.10.0' + implementation 'com.slack.api:slack-app-backend:1.28.0' + implementation 'com.slack.api:slack-api-model:1.28.0' } tasks.named('test') { - useJUnitPlatform() + useJUnitPlatform() } From 7effe740551d693f8563f19665b35f6dec207b71 Mon Sep 17 00:00:00 2001 From: KWY Date: Tue, 12 Dec 2023 18:56:19 +0900 Subject: [PATCH 2/7] =?UTF-8?q?#240=20[feat]=20querydsl=20config=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/querydsl/QueryDslConfig.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/java/com/asap/server/config/querydsl/QueryDslConfig.java diff --git a/src/main/java/com/asap/server/config/querydsl/QueryDslConfig.java b/src/main/java/com/asap/server/config/querydsl/QueryDslConfig.java new file mode 100644 index 00000000..e0856054 --- /dev/null +++ b/src/main/java/com/asap/server/config/querydsl/QueryDslConfig.java @@ -0,0 +1,19 @@ +package com.asap.server.config.querydsl; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +@Configuration +public class QueryDslConfig { + @PersistenceContext + private EntityManager entityManager; + + @Bean + public JPAQueryFactory jpaQueryFactory() { + return new JPAQueryFactory(entityManager); + } +} From 7f5d22acb76246405e7bcee48cfe53f1738f126f Mon Sep 17 00:00:00 2001 From: KWY Date: Tue, 12 Dec 2023 18:57:11 +0900 Subject: [PATCH 3/7] #240 [feat] create custom user repository --- .../server/repository/MeetingRepository.java | 2 -- .../server/repository/UserRepository.java | 27 ------------------- .../repository/user/UserRepository.java | 20 ++++++++++++++ .../repository/user/UserRepositoryCustom.java | 10 +++++++ .../repository/user/UserRepositoryImpl.java | 25 +++++++++++++++++ 5 files changed, 55 insertions(+), 29 deletions(-) delete mode 100644 src/main/java/com/asap/server/repository/UserRepository.java create mode 100644 src/main/java/com/asap/server/repository/user/UserRepository.java create mode 100644 src/main/java/com/asap/server/repository/user/UserRepositoryCustom.java create mode 100644 src/main/java/com/asap/server/repository/user/UserRepositoryImpl.java diff --git a/src/main/java/com/asap/server/repository/MeetingRepository.java b/src/main/java/com/asap/server/repository/MeetingRepository.java index 7857163e..92bc8aa0 100644 --- a/src/main/java/com/asap/server/repository/MeetingRepository.java +++ b/src/main/java/com/asap/server/repository/MeetingRepository.java @@ -13,8 +13,6 @@ public interface MeetingRepository extends Repository { Meeting save(final Meeting meeting); - void saveAndFlush(final Meeting meeting); - @EntityGraph(attributePaths = {"host"}) @Query("select m from Meeting m where m.id = :id") Optional findByIdWithHost(@Param("id") final Long id); diff --git a/src/main/java/com/asap/server/repository/UserRepository.java b/src/main/java/com/asap/server/repository/UserRepository.java deleted file mode 100644 index 7d61172f..00000000 --- a/src/main/java/com/asap/server/repository/UserRepository.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.asap.server.repository; - -import com.asap.server.domain.Meeting; -import com.asap.server.domain.User; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.Repository; -import org.springframework.data.repository.query.Param; - -import java.util.List; -import java.util.Optional; - -public interface UserRepository extends Repository { - User save(final User user); - - @Modifying(clearAutomatically = true) - @Query("update User u set u.isFixed = true where u.meeting = :meeting and u.id in :userIds") - void updateUserIsFixedByMeeting(@Param("meeting") final Meeting meeting, @Param("userIds") final List users); - - List findByMeetingAndIsFixed(final Meeting meeting, final boolean isFixed); - - Optional findById(final Long id); - - List findByMeeting(final Meeting meeting); - - int countByMeeting(final Meeting meeting); -} diff --git a/src/main/java/com/asap/server/repository/user/UserRepository.java b/src/main/java/com/asap/server/repository/user/UserRepository.java new file mode 100644 index 00000000..844d3162 --- /dev/null +++ b/src/main/java/com/asap/server/repository/user/UserRepository.java @@ -0,0 +1,20 @@ +package com.asap.server.repository.user; + +import com.asap.server.domain.Meeting; +import com.asap.server.domain.User; +import org.springframework.data.repository.Repository; + +import java.util.List; +import java.util.Optional; + +public interface UserRepository extends Repository, UserRepositoryCustom { + User save(final User user); + + List findByMeetingAndIsFixed(final Meeting meeting, final boolean isFixed); + + Optional findById(final Long id); + + List findByMeeting(final Meeting meeting); + + int countByMeeting(final Meeting meeting); +} diff --git a/src/main/java/com/asap/server/repository/user/UserRepositoryCustom.java b/src/main/java/com/asap/server/repository/user/UserRepositoryCustom.java new file mode 100644 index 00000000..c16d2beb --- /dev/null +++ b/src/main/java/com/asap/server/repository/user/UserRepositoryCustom.java @@ -0,0 +1,10 @@ +package com.asap.server.repository.user; + +import com.asap.server.domain.Meeting; +import com.asap.server.domain.User; + +import java.util.List; + +public interface UserRepositoryCustom { + void updateUserIsFixedByMeeting(final Meeting meeting, final List users); +} diff --git a/src/main/java/com/asap/server/repository/user/UserRepositoryImpl.java b/src/main/java/com/asap/server/repository/user/UserRepositoryImpl.java new file mode 100644 index 00000000..29bbf785 --- /dev/null +++ b/src/main/java/com/asap/server/repository/user/UserRepositoryImpl.java @@ -0,0 +1,25 @@ +package com.asap.server.repository.user; + +import com.asap.server.domain.Meeting; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +import static com.asap.server.domain.QUser.user; + +@RequiredArgsConstructor +public class UserRepositoryImpl implements UserRepositoryCustom { + private final JPAQueryFactory queryFactory; + + @Override + public void updateUserIsFixedByMeeting(Meeting meeting, List users) { + queryFactory.update(user) + .set(user.isFixed, true) + .where( + user.meeting.eq(meeting) + .and(user.id.in(users)) + ) + .execute(); + } +} From 5bded00460bde97d377c5e071359fdb94fc9716d Mon Sep 17 00:00:00 2001 From: KWY Date: Tue, 12 Dec 2023 18:58:04 +0900 Subject: [PATCH 4/7] =?UTF-8?q?#240=20[feat]=20service=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/asap/server/service/MeetingService.java | 2 -- src/main/java/com/asap/server/service/UserService.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/asap/server/service/MeetingService.java b/src/main/java/com/asap/server/service/MeetingService.java index 6634b9dd..575ce0d8 100644 --- a/src/main/java/com/asap/server/service/MeetingService.java +++ b/src/main/java/com/asap/server/service/MeetingService.java @@ -104,8 +104,6 @@ public void confirmMeeting( LocalDateTime fixedEndDateTime = LocalDateTime.of(fixedDate, endTime); meeting.setConfirmedDateTime(fixedStartDateTime, fixedEndDateTime); - meetingRepository.saveAndFlush(meeting); - userService.setFixedUsers(meeting, meetingConfirmRequestDto.getUsers()); } diff --git a/src/main/java/com/asap/server/service/UserService.java b/src/main/java/com/asap/server/service/UserService.java index bb32297a..e0974fc6 100644 --- a/src/main/java/com/asap/server/service/UserService.java +++ b/src/main/java/com/asap/server/service/UserService.java @@ -20,7 +20,7 @@ import com.asap.server.exception.model.NotFoundException; import com.asap.server.exception.model.UnauthorizedException; import com.asap.server.repository.MeetingRepository; -import com.asap.server.repository.UserRepository; +import com.asap.server.repository.user.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; From 75e79a6b6cd879864d21242a1329dac900ac3379 Mon Sep 17 00:00:00 2001 From: KWY Date: Tue, 12 Dec 2023 21:27:43 +0900 Subject: [PATCH 5/7] =?UTF-8?q?#240=20[feat]=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=20=EC=8B=9C=20fetch=20join=20=EB=A1=9C=EC=A7=81=20querydsl?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/repository/MeetingRepository.java | 19 -------------- .../repository/meeting/MeetingRepository.java | 12 +++++++++ .../meeting/MeetingRepositoryCustom.java | 9 +++++++ .../meeting/MeetingRepositoryImpl.java | 26 +++++++++++++++++++ .../asap/server/service/MeetingService.java | 2 +- .../com/asap/server/service/UserService.java | 2 +- 6 files changed, 49 insertions(+), 21 deletions(-) delete mode 100644 src/main/java/com/asap/server/repository/MeetingRepository.java create mode 100644 src/main/java/com/asap/server/repository/meeting/MeetingRepository.java create mode 100644 src/main/java/com/asap/server/repository/meeting/MeetingRepositoryCustom.java create mode 100644 src/main/java/com/asap/server/repository/meeting/MeetingRepositoryImpl.java diff --git a/src/main/java/com/asap/server/repository/MeetingRepository.java b/src/main/java/com/asap/server/repository/MeetingRepository.java deleted file mode 100644 index 92bc8aa0..00000000 --- a/src/main/java/com/asap/server/repository/MeetingRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.asap.server.repository; - -import com.asap.server.domain.Meeting; -import org.springframework.data.jpa.repository.EntityGraph; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.Repository; -import org.springframework.data.repository.query.Param; - -import java.util.Optional; - -public interface MeetingRepository extends Repository { - Optional findById(final Long id); - - Meeting save(final Meeting meeting); - - @EntityGraph(attributePaths = {"host"}) - @Query("select m from Meeting m where m.id = :id") - Optional findByIdWithHost(@Param("id") final Long id); -} diff --git a/src/main/java/com/asap/server/repository/meeting/MeetingRepository.java b/src/main/java/com/asap/server/repository/meeting/MeetingRepository.java new file mode 100644 index 00000000..746762bd --- /dev/null +++ b/src/main/java/com/asap/server/repository/meeting/MeetingRepository.java @@ -0,0 +1,12 @@ +package com.asap.server.repository.meeting; + +import com.asap.server.domain.Meeting; +import org.springframework.data.repository.Repository; + +import java.util.Optional; + +public interface MeetingRepository extends Repository, MeetingRepositoryCustom { + Optional findById(final Long id); + + Meeting save(final Meeting meeting); +} diff --git a/src/main/java/com/asap/server/repository/meeting/MeetingRepositoryCustom.java b/src/main/java/com/asap/server/repository/meeting/MeetingRepositoryCustom.java new file mode 100644 index 00000000..3583a156 --- /dev/null +++ b/src/main/java/com/asap/server/repository/meeting/MeetingRepositoryCustom.java @@ -0,0 +1,9 @@ +package com.asap.server.repository.meeting; + +import com.asap.server.domain.Meeting; + +import java.util.Optional; + +public interface MeetingRepositoryCustom { + Optional findByIdWithHost(final Long id); +} diff --git a/src/main/java/com/asap/server/repository/meeting/MeetingRepositoryImpl.java b/src/main/java/com/asap/server/repository/meeting/MeetingRepositoryImpl.java new file mode 100644 index 00000000..7165d485 --- /dev/null +++ b/src/main/java/com/asap/server/repository/meeting/MeetingRepositoryImpl.java @@ -0,0 +1,26 @@ +package com.asap.server.repository.meeting; + +import com.asap.server.domain.Meeting; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; + +import java.util.Optional; + +import static com.asap.server.domain.QMeeting.meeting; +import static com.asap.server.domain.QUser.user; + +@RequiredArgsConstructor +public class MeetingRepositoryImpl implements MeetingRepositoryCustom { + private final JPAQueryFactory queryFactory; + + @Override + public Optional findByIdWithHost(Long id) { + return Optional.ofNullable( + queryFactory.selectFrom(meeting) + .where(meeting.id.eq(id)) + .join(meeting.host, user) + .fetchJoin() + .fetchOne() + ); + } +} diff --git a/src/main/java/com/asap/server/service/MeetingService.java b/src/main/java/com/asap/server/service/MeetingService.java index 575ce0d8..fe9d9aef 100644 --- a/src/main/java/com/asap/server/service/MeetingService.java +++ b/src/main/java/com/asap/server/service/MeetingService.java @@ -22,7 +22,7 @@ import com.asap.server.exception.model.ForbiddenException; import com.asap.server.exception.model.NotFoundException; import com.asap.server.exception.model.UnauthorizedException; -import com.asap.server.repository.MeetingRepository; +import com.asap.server.repository.meeting.MeetingRepository; import com.asap.server.service.vo.BestMeetingTimeVo; import com.asap.server.service.vo.TimeBlocksByDateVo; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/asap/server/service/UserService.java b/src/main/java/com/asap/server/service/UserService.java index e0974fc6..d9fe35f2 100644 --- a/src/main/java/com/asap/server/service/UserService.java +++ b/src/main/java/com/asap/server/service/UserService.java @@ -19,7 +19,7 @@ import com.asap.server.exception.model.HostTimeForbiddenException; import com.asap.server.exception.model.NotFoundException; import com.asap.server.exception.model.UnauthorizedException; -import com.asap.server.repository.MeetingRepository; +import com.asap.server.repository.meeting.MeetingRepository; import com.asap.server.repository.user.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.security.crypto.password.PasswordEncoder; From 6bc2dc536cebae5091dce62bc9bb93291ab3a8ae Mon Sep 17 00:00:00 2001 From: KWY Date: Tue, 12 Dec 2023 21:38:49 +0900 Subject: [PATCH 6/7] =?UTF-8?q?#240=20[chore]=20code=20deploy=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/dev-cd.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/dev-cd.yml b/.github/workflows/dev-cd.yml index 750f7b5f..e9e1fd24 100644 --- a/.github/workflows/dev-cd.yml +++ b/.github/workflows/dev-cd.yml @@ -82,15 +82,15 @@ jobs: - name: Upload to S3 run: aws s3 cp --region ap-northeast-2 ./asap_dev_server.zip s3://$S3_BUCKET_NAME/ - # Deploy - - name: Deploy - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_KEY }} - run: - aws deploy create-deployment - --application-name asap-dev-codedeploy - --deployment-group-name asap-dev-codedeploy-group - --file-exists-behavior OVERWRITE - --s3-location bucket=asap-develop-bucket,bundleType=zip,key=asap_dev_server.zip - --region ap-northeast-2 +# # Deploy +# - name: Deploy +# env: +# AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }} +# AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_KEY }} +# run: +# aws deploy create-deployment +# --application-name asap-dev-codedeploy +# --deployment-group-name asap-dev-codedeploy-group +# --file-exists-behavior OVERWRITE +# --s3-location bucket=asap-develop-bucket,bundleType=zip,key=asap_dev_server.zip +# --region ap-northeast-2 From 4a76df50e6a15c54163c55b7846a85cac2f8b4df Mon Sep 17 00:00:00 2001 From: KWY Date: Wed, 13 Dec 2023 11:04:07 +0900 Subject: [PATCH 7/7] =?UTF-8?q?#240=20[test]=20fetch=20join=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MeetingRepositoryCustomTest.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/test/java/com/asap/server/repository/MeetingRepositoryCustomTest.java diff --git a/src/test/java/com/asap/server/repository/MeetingRepositoryCustomTest.java b/src/test/java/com/asap/server/repository/MeetingRepositoryCustomTest.java new file mode 100644 index 00000000..294b5a37 --- /dev/null +++ b/src/test/java/com/asap/server/repository/MeetingRepositoryCustomTest.java @@ -0,0 +1,68 @@ +package com.asap.server.repository; + +import com.asap.server.config.querydsl.QueryDslConfig; +import com.asap.server.domain.Meeting; +import com.asap.server.domain.Place; +import com.asap.server.domain.User; +import com.asap.server.domain.enums.Duration; +import com.asap.server.domain.enums.PlaceType; +import com.asap.server.domain.enums.Role; +import com.asap.server.repository.meeting.MeetingRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; + +import javax.persistence.EntityManager; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +@DataJpaTest +@Import(QueryDslConfig.class) +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +public class MeetingRepositoryCustomTest { + @Autowired + private MeetingRepository meetingRepository; + + @Autowired + private EntityManager em; + + @Test + @DisplayName("방장이 로그인을 할 때, 방장 정보도 함께 불러온다.") + void fetchJoinTest() { + final Place place = Place.builder() + .placeType(PlaceType.OFFLINE) + .build(); + + final Meeting meeting = Meeting.builder() + .title("회의 테스트") + .password("0000") + .additionalInfo("") + .duration(Duration.HALF) + .place(place) + .build(); + + final User user = User.builder() + .meeting(meeting) + .name("강원용") + .role(Role.HOST) + .isFixed(false) + .build(); + meeting.setHost(user); + + em.persist(meeting); + em.persist(user); + em.flush(); + em.clear(); + + // when + Meeting result = meetingRepository.findByIdWithHost(meeting.getId()).get(); + User host = result.getHost(); + + // then + assertThat(host).isNotNull(); + } + +}