Skip to content

Commit

Permalink
Merge pull request #53 from MAKAR-iOS/fix/#52
Browse files Browse the repository at this point in the history
[Fix/#52] 최근 경로 생성 시, route_id의 unique 제약 조건 위반 에러 해결
  • Loading branch information
chaeyeon0130 authored Aug 4, 2024
2 parents 1685984 + c726afb commit b39e407
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 50 deletions.
5 changes: 3 additions & 2 deletions src/main/java/makar/dev/converter/RouteConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import makar.dev.dto.response.RouteResponse;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -70,7 +70,8 @@ public static RouteResponse.BriefRouteDto toBriefRouteDto(Route route){
}

public static List<RouteResponse.BriefRouteDtoWithRouteId> toBriefRouteDtoList(List<Route> routes){
routes.sort(Comparator.comparingInt(Route::getRecentOrder).reversed());
// recent_route_id가 큰 것부터 조회되도록(최신순) 리스트의 순서를 뒤집음
Collections.reverse(routes);

return routes.stream()
.map(route ->
Expand Down
43 changes: 43 additions & 0 deletions src/main/java/makar/dev/domain/RecentRoute.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package makar.dev.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class RecentRoute {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "recent_route_id")
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "route_id")
private Route route;

@Builder
public RecentRoute(User user, Route route) {
this.user = user;
this.route = route;

// 객체 단에서 User의 최근 경로 리스트에 해당 RecentRoute를 넣어주는
// 연관관계 편의메서드
user.getRecentRouteList().add(this);
}
}
8 changes: 0 additions & 8 deletions src/main/java/makar/dev/domain/Route.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,7 @@ public class Route {
@Column(nullable = false)
private List<SubRoute> subRouteList;

// 최근 경로 리스트 내 순서
@Column(name = "recent_order")
private int recentOrder;

public void updateSchedule(Schedule schedule){
this.schedule = schedule;
}

public void setRecentOrder(int recentOrder) {
this.recentOrder = recentOrder;
}
}
49 changes: 13 additions & 36 deletions src/main/java/makar/dev/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import makar.dev.common.exception.GeneralException;
import makar.dev.common.status.ErrorStatus;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Getter
@Setter
Expand Down Expand Up @@ -46,8 +46,8 @@ public class User {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<Noti> notiList; //알림 설정

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Route> recentRouteList; //최근 경로 리스트
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<RecentRoute> recentRouteList = new ArrayList<>();

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Route> favoriteRouteList; //즐겨찾는 경로 리스트
Expand All @@ -62,40 +62,17 @@ public User(String userName){
public boolean isFavoriteSchoolStationExist(){return this.favoriteSchoolStation != null;}
public void addNotiList(Noti noti){this.notiList.add(noti);}
public void addFavoriteRoute(Route route){this.favoriteRouteList.add(favoriteRouteList.size(), route);}
public void addRecentRouteList(Route route) {
int maxOrder = -1;
Route existingRoute = null;

// 동일한 routeId를 가진 Route가 이미 최근 경로 리스트에 존재하는지 확인
for (Route r : this.recentRouteList) {
if (r.getRouteId().equals(route.getRouteId())) {
existingRoute = r;
}
if (r.getRecentOrder() > maxOrder) {
maxOrder = r.getRecentOrder();
}
}

if (existingRoute != null) {
// 이미 리스트에 존재하는 경우 recentOrder만 수정
existingRoute.setRecentOrder(maxOrder + 1);
} else {
// 최근 경로 리스트 사이즈 최대 5개 유지
if (this.recentRouteList.size() >= 5) {
this.recentRouteList.remove(0);
}

// 새로운 Route일 경우 리스트의 마지막에 추가
route.setRecentOrder(maxOrder + 1);
this.recentRouteList.add(route);
}
// user의 최근 경로를 Route 타입의 List로 반환하는 함수
public List<Route> findRecentRouteList() {
return this.recentRouteList.stream()
.map(RecentRoute::getRoute)
.collect(Collectors.toList());
}
public void removeRecentRouteList(Route route) {
boolean removed = this.recentRouteList.remove(route);
if (!removed) {
throw new GeneralException(ErrorStatus.NOT_FOUND_IN_RECENT_ROUTE_LIST);
}
// user의 최근 경로 리스트에서 특정 최근 경로 삭제
public void removeRecentRoute(RecentRoute route) {
this.getRecentRouteList().remove(route);
}
// user의 최근 경로 리스트 비우기
public void clearRecentRouteList() {
this.recentRouteList.clear();
}
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/makar/dev/repository/RecentRouteRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package makar.dev.repository;

import makar.dev.domain.RecentRoute;
import makar.dev.domain.Route;
import makar.dev.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface RecentRouteRepository extends JpaRepository<RecentRoute, Long> {
Optional<RecentRoute> findByUserAndRoute(User user, Route route);
void deleteByUser(User user);
}
38 changes: 34 additions & 4 deletions src/main/java/makar/dev/service/RouteService.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class RouteService {
private final ScheduleRepository scheduleRepository;
private final UserRepository userRepository;
private final NotiRepository notiRepository;
private final RecentRouteRepository recentRouteRepository;
private final APIManager apiManager;
private final MakarManager makarManager;
private final TransferService transferService;
Expand Down Expand Up @@ -67,8 +68,9 @@ public RouteResponse.RouteDto setRoute(Long userId, Long routeId){
user.addNotiList(makarNoti);
user.addNotiList(getOffNoti);

// 해당 경로, 유저의 최근 경로 리스트에 저장
user.addRecentRouteList(route);
// 해당 경로, 유저 정보를 갖는 RecentRoute 객체 생성 후 저장
addRecentRoute(user, route);

return RouteConverter.toRouteDto(route);
}

Expand Down Expand Up @@ -315,11 +317,34 @@ private String getDestinationTime(String sourceTime, int totalTime) {
return sdf.format(calendar.getTime());
}

// 특정 경로, 유저를 기반으로 하는 RecentRoute 객체 생성 후 저장
@Transactional
public void addRecentRoute(User user, Route route) {
// 동일한 routeId를 가진 Route가 이미 최근 경로 리스트에 존재한다면
// DB와 리스트에서 제거
recentRouteRepository.findByUserAndRoute(user, route).ifPresent(
recentRoute -> {
recentRouteRepository.delete(recentRoute);
user.removeRecentRoute(recentRoute);
}
);

// 최근 경로 리스트 사이즈 최대 5개 유지
if (user.getRecentRouteList().size() >= 5) {
RecentRoute recentRoute = user.getRecentRouteList().get(0);
recentRouteRepository.delete(recentRoute);
}

// 새로운 RecentRoute 생성 및 저장
RecentRoute newRecentRoute = new RecentRoute(user, route);
recentRouteRepository.save(newRecentRoute);
}

// 최근 경로 리스트 조회하기
public RouteResponse.RecentRouteListDto getAllRecentRoute(Long userId) {
User user = findUserById(userId);
return RouteResponse.RecentRouteListDto.builder()
.recentRouteList(RouteConverter.toBriefRouteDtoList(user.getRecentRouteList()))
.recentRouteList(RouteConverter.toBriefRouteDtoList(user.findRecentRouteList()))
.build();
}

Expand All @@ -328,13 +353,18 @@ public RouteResponse.RecentRouteListDto getAllRecentRoute(Long userId) {
public void deleteRecentRoute(Long userId, Long routeId) {
User user = findUserById(userId);
Route route = findRouteById(routeId);
user.removeRecentRouteList(route);
RecentRoute recentRoute = recentRouteRepository.findByUserAndRoute(user, route).orElseThrow(
() -> new GeneralException(ErrorStatus.NOT_FOUND_IN_RECENT_ROUTE_LIST)
);
recentRouteRepository.delete(recentRoute);
user.removeRecentRoute(recentRoute);
}

// 모든 최근 경로 삭제
@Transactional
public void deleteAllRecentRoute(Long userId) {
User user = findUserById(userId);
recentRouteRepository.deleteByUser(user);
user.clearRecentRouteList();
}
}

0 comments on commit b39e407

Please sign in to comment.