Skip to content

Commit f99db57

Browse files
ehddhks194pjw81226jlhyunii
authored
[RELEASE] dev > release 배포 (#142)
* fix: 오탈자 수정 * fix: scheduler 시간 변경 * chore : server-private 수정 * fix : 옷차림 요약 정보 조회 API 실행 시 500 에러 해결 * chore : server-private 최신 업데이트 반영 * fix: 즐겨찾기 목록조회 버그와 기본위치변경 에러 수정 (#139) * fix: 중기예보조회 500에러 해결 (#141) --------- Co-authored-by: jwpark <woojang812@gmail.com> Co-authored-by: jlhyunii <jhpark4692@naver.com> Co-authored-by: jlhyunii <147504146+jlhyunii@users.noreply.github.com>
1 parent a04a46a commit f99db57

5 files changed

Lines changed: 49 additions & 29 deletions

File tree

src/main/java/com/weady/weady/domain/fashion/service/FashionService.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.weady.weady.domain.location.entity.Location;
1010
import com.weady.weady.domain.location.repository.LocationRepository;
1111
import com.weady.weady.domain.user.entity.User;
12+
import com.weady.weady.domain.user.repository.UserFavoriteLocationRepository;
1213
import com.weady.weady.domain.user.repository.UserRepository;
1314
import com.weady.weady.domain.weather.entity.DailySummary;
1415
import com.weady.weady.domain.weather.entity.LocationWeatherSnapshot;
@@ -21,6 +22,7 @@
2122
import com.weady.weady.common.util.SecurityUtil;
2223
import lombok.RequiredArgsConstructor;
2324
import org.springframework.stereotype.Service;
25+
import org.springframework.transaction.annotation.Transactional;
2426

2527
import java.time.LocalDateTime;
2628
import java.time.format.DateTimeFormatter;
@@ -38,6 +40,7 @@ public class FashionService {
3840
private final UserRepository userRepository;
3941
private final LocationRepository locationRepository;
4042
private final DailySummaryRepository dailySummaryRepository;
43+
private final UserFavoriteLocationRepository userFavoriteLocationRepository;
4144

4245
/**
4346
* 홈 화면에서 옷차림 요약 정보를 조회
@@ -52,7 +55,7 @@ public FashionSummaryResponseDto getFashionSummary() {
5255
User user = userRepository.findById(userId)
5356
.orElseThrow(() -> new BusinessException(UserErrorCode.USER_NOT_FOUND));
5457

55-
Long locationId = getUserDefaultLocationId(user);
58+
Long locationId = getUserDefaultLocationId(userId);
5659

5760
LocalDateTime today = LocalDateTime.now();
5861
int date = Integer.parseInt(today.format(DateTimeFormatter.ofPattern("yyyyMMdd")));
@@ -67,7 +70,7 @@ public FashionSummaryResponseDto getFashionSummary() {
6770
Fashion fashion = fashionRepository
6871
.findByTemperatureRange(feelTemp)
6972
.orElseThrow(() -> new BusinessException(FashionErrorCode.FASHION_NOT_FOUND));
70-
73+
7174
return FashionMapper.toSummaryResponse(locationId, fashion);
7275
}
7376

@@ -85,7 +88,7 @@ public FashionDetailResponseDto getFashionDetail() {
8588
User user = userRepository.findById(userId)
8689
.orElseThrow(() -> new BusinessException(UserErrorCode.USER_NOT_FOUND));
8790

88-
Long locationId = getUserDefaultLocationId(user);
91+
Long locationId = getUserDefaultLocationId(userId);
8992

9093
LocalDateTime today = LocalDateTime.now();
9194
int date = Integer.parseInt(today.format(DateTimeFormatter.ofPattern("yyyyMMdd")));
@@ -142,12 +145,9 @@ private Fashion findFashionFor(float feelTmp, List<Fashion> fashions) {
142145
.orElseThrow(() -> new BusinessException(FashionErrorCode.FASHION_NOT_FOUND));
143146
}
144147

145-
private Long getUserDefaultLocationId(User user){
146-
if (user.getDefaultLocation() != null && user.getDefaultLocation().getLocation() != null) {
147-
return user.getDefaultLocation().getLocation().getId();
148-
}
149-
return Optional.ofNullable(user.getNowLocation())
150-
.map(Location::getId)
148+
@Transactional(readOnly = true)
149+
public Long getUserDefaultLocationId(Long userId){
150+
return userFavoriteLocationRepository.findDefaultOrNowLocationId(userId)
151151
.orElseThrow(() -> new BusinessException(UserErrorCode.USER_DEFAULT_LOCATION_NOT_FOUNT));
152152
}
153-
}
153+
}

src/main/java/com/weady/weady/domain/user/entity/User.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class User extends BaseEntity {
2929
private Location nowLocation;
3030

3131
@Setter
32-
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
32+
@OneToOne(fetch = FetchType.LAZY)
3333
@JoinColumn(name = "default_location_id")
3434
private UserFavoriteLocation defaultLocation;
3535

src/main/java/com/weady/weady/domain/user/repository/UserFavoriteLocationRepository.java

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import java.time.LocalDate;
1111
import java.util.List;
12+
import java.util.Optional;
1213

1314
public interface UserFavoriteLocationRepository extends JpaRepository<UserFavoriteLocation, Long> {
1415

@@ -17,25 +18,44 @@ public interface UserFavoriteLocationRepository extends JpaRepository<UserFavori
1718

1819
List<UserFavoriteLocation> findByUser(User user);
1920

20-
/**
21-
* --- [성능 최적화] ---
22-
* 특정 사용자의 모든 즐겨찾기 정보를 관련 날씨/요약 데이터와 함께 한 번의 쿼리로 조회합니다.
23-
* N+1 문제를 해결하기 위해 여러 엔티티를 LEFT JOIN으로 연결합니다.
24-
*
25-
* @param userId 조회할 사용자의 ID
26-
* @param reportDate 조회할 일일 요약 정보의 날짜 (오늘)
27-
* @param currentTime 조회할 현재 날씨 정보의 시간 (예: 1500)
28-
* @return Object 배열의 리스트. 각 배열은 [UserFavoriteLocation, LocationWeatherShortDetail, DailySummary] 순서로 구성됩니다.
29-
*/
30-
@Query("SELECT uf, lwsd, ds " +
31-
"FROM UserFavoriteLocation uf " +
32-
"JOIN FETCH uf.location l " +
33-
"LEFT JOIN LocationWeatherShortDetail lwsd ON lwsd.location = l AND lwsd.time = :currentTime " +
34-
"LEFT JOIN DailySummary ds ON ds.location = l AND ds.reportDate = :reportDate " +
35-
"WHERE uf.user.id = :userId")
21+
22+
@Query("""
23+
select uf, lwsd, ds
24+
from UserFavoriteLocation uf
25+
join uf.location l
26+
left join LocationWeatherShortDetail lwsd
27+
on lwsd.location = l
28+
and lwsd.time = :currentTime
29+
and lwsd.id = (
30+
select max(s.id)
31+
from LocationWeatherShortDetail s
32+
where s.location = l
33+
and s.time = :currentTime
34+
)
35+
left join DailySummary ds
36+
on ds.location = l
37+
and ds.reportDate = :reportDate
38+
and ds.id = (
39+
select max(d2.id)
40+
from DailySummary d2
41+
where d2.location = l
42+
and d2.reportDate = :reportDate
43+
)
44+
where uf.user.id = :userId
45+
""")
3646
List<Object[]> findFavoritesWithDetailsByUserId(
3747
@Param("userId") Long userId,
3848
@Param("reportDate") LocalDate reportDate,
3949
@Param("currentTime") int currentTime
4050
);
51+
52+
@Query("""
53+
select coalesce(dl.location.id, nl.id)
54+
from User u
55+
left join u.defaultLocation dl
56+
left join dl.location
57+
left join u.nowLocation nl
58+
where u.id = :userId
59+
""")
60+
Optional<Long> findDefaultOrNowLocationId(Long userId);
4161
}

src/main/java/com/weady/weady/domain/user/service/UserService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,9 @@ public GetUserDefaultLocationResponse getUserDefaultLocation(){
137137
@Transactional(readOnly = true)
138138
public boolean checkNicknameDuplication(String nickname) {
139139
return userRepository.existsUserByName(nickname);
140-
141140
}
142141

142+
143143
private void runAfterCommit(Runnable task) {
144144
if (TransactionSynchronizationManager.isActualTransactionActive()) {
145145
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {

src/main/java/com/weady/weady/domain/weather/mapper/WeatherMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public static GetLocationWeatherShortDetailResponse toShortWeatherResponse(
6464

6565
public static GetWeatherMidDetailResponse toMidWeatherResponse(WeatherMidDetail weatherMid) {
6666

67-
LocalDate localDate = LocalDate.parse(String.valueOf(weatherMid.getDate()), DateTimeFormatter.ofPattern("yyyyMMdd"));
67+
LocalDate localDate = LocalDate.parse(String.valueOf(weatherMid.getDate()));
6868

6969
return GetWeatherMidDetailResponse.builder()
7070
.dayOfWeek(localDate.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.KOREAN))

0 commit comments

Comments
 (0)