Skip to content
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package life.mosu.mosuserver.application.school;


import java.util.List;
import life.mosu.mosuserver.domain.school.SchoolJpaRepository;
import life.mosu.mosuserver.presentation.school.dto.AvailableSchoolResponse;
import life.mosu.mosuserver.presentation.school.dto.SchoolRegistrationRequest;
import life.mosu.mosuserver.presentation.school.dto.SchoolResponse;
import lombok.RequiredArgsConstructor;
Expand All @@ -15,12 +15,21 @@
public class SchoolService {

private final SchoolJpaRepository schoolJpaRepository;
private final SchoolQuotaCacheManager schoolQuotaCacheManager;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify cache manager implementation for performance and reliability.

The new dependency schoolQuotaCacheManager is properly injected, but ensure that:

  1. The cache manager is optimized for batch operations if dealing with many schools
  2. It has proper error handling and fallback mechanisms
  3. Cache invalidation strategies are in place for real-time accuracy

🏁 Script executed:

#!/bin/bash
# Description: Verify the SchoolQuotaCacheManager implementation for performance and error handling

# Search for the cache manager implementation
ast-grep --pattern 'class SchoolQuotaCacheManager {
  $$$
}'

# Also search for the getSchoolApplicationCounts method implementation
ast-grep --pattern 'getSchoolApplicationCounts($$$) {
  $$$
}'

Length of output: 127


🏁 Script executed:

#!/bin/bash
# Locate the SchoolQuotaCacheManager implementation file
echo "Searching for SchoolQuotaCacheManager.java..."
fd --extension java SchoolQuotaCacheManager

# If found, inspect class declaration and key methods
for file in $(fd --extension java SchoolQuotaCacheManager); do
  echo -e "\n--- Inspecting $file ---"
  # Show class declaration and first 200 lines
  sed -n '1,200p' "$file" | sed -n '/class SchoolQuotaCacheManager/,/^}/p'
  echo -e "\nMethod definitions in $file:"
  grep -RnoP 'public\s+.*getSchoolApplicationCounts' "$file"
  grep -RnoP 'public\s+.*batch' "$file"
  grep -RnoP -i 'error|exception|fail' "$file"
  grep -RnoP -i 'invalidate|evict|clear' "$file"
done

Length of output: 3583


Implement batching, error handling, and cache invalidation in SchoolQuotaCacheManager

The current implementation in
src/main/java/life/mosu/mosuserver/application/school/SchoolQuotaCacheManager.java
uses per‐key loops and has no error handling or eviction logic. To improve performance and reliability, please:

  • Replace individual set calls in cacheSchoolMaxCapacities() and cacheSchoolCurrentApplicationCounts() with Redis pipelining or opsForValue().multiSet() for bulk writes.
  • Wrap all Redis operations (set, get, increment, decrement) in try/catch blocks and fall back to schoolRepository reads if Redis is unavailable.
  • Add cache expiration or explicit invalidation methods (e.g. redisTemplate.expire(...) or invalidateSchoolCache(String schoolName)) to ensure real-time accuracy.
🤖 Prompt for AI Agents
In
src/main/java/life/mosu/mosuserver/application/school/SchoolQuotaCacheManager.java
around line 18, the current cache methods use per-key loops without error
handling or cache eviction. Refactor cacheSchoolMaxCapacities() and
cacheSchoolCurrentApplicationCounts() to use Redis pipelining or
opsForValue().multiSet() for bulk writes to improve performance. Wrap all Redis
operations like set, get, increment, and decrement in try/catch blocks to handle
Redis failures gracefully by falling back to schoolRepository reads. Add cache
expiration settings or implement explicit cache invalidation methods such as
invalidateSchoolCache(String schoolName) using redisTemplate.expire(...) to
maintain cache accuracy.


@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public List<SchoolResponse> getSchools() {
public List<AvailableSchoolResponse> getAvailableSchools() {

return schoolJpaRepository.findAll()
.stream()
.map(SchoolResponse::from)
.map(school -> {
SchoolResponse schoolResponse = SchoolResponse.from(school);

Long currentQuantity = schoolQuotaCacheManager.getSchoolApplicationCounts(
schoolResponse.schoolName());

return AvailableSchoolResponse.from(schoolResponse, currentQuantity);
})
Comment on lines +25 to +32
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Add error handling and consider performance optimization.

The implementation has several potential issues:

  1. No error handling: The cache manager call could fail, causing the entire operation to fail
  2. N+1 problem: Making individual cache calls for each school could be inefficient
  3. Null handling: No handling for null currentQuantity values

Consider this improved implementation:

 return schoolJpaRepository.findAll()
         .stream()
-        .map(school -> {
-            SchoolResponse schoolResponse = SchoolResponse.from(school);
-
-            Long currentQuantity = schoolQuotaCacheManager.getSchoolApplicationCounts(
-                    schoolResponse.schoolName());
-
-            return AvailableSchoolResponse.from(schoolResponse, currentQuantity);
-        })
+        .map(school -> {
+            SchoolResponse schoolResponse = SchoolResponse.from(school);
+            
+            try {
+                Long currentQuantity = schoolQuotaCacheManager.getSchoolApplicationCounts(
+                        schoolResponse.schoolName());
+                return AvailableSchoolResponse.from(schoolResponse, 
+                        currentQuantity != null ? currentQuantity : 0L);
+            } catch (Exception e) {
+                // Log error and return with default count
+                log.warn("Failed to get application count for school: {}", 
+                        schoolResponse.schoolName(), e);
+                return AvailableSchoolResponse.from(schoolResponse, 0L);
+            }
+        })
         .toList();

For better performance, consider batch operations if the cache manager supports it:

// Get all school names first
List<String> schoolNames = schoolJpaRepository.findAll()
    .stream()
    .map(School::getName)
    .toList();

// Batch get application counts
Map<String, Long> applicationCounts = schoolQuotaCacheManager.getBatchApplicationCounts(schoolNames);

// Then map with cached results
return schoolJpaRepository.findAll()
    .stream()
    .map(school -> {
        SchoolResponse schoolResponse = SchoolResponse.from(school);
        Long currentQuantity = applicationCounts.getOrDefault(schoolResponse.schoolName(), 0L);
        return AvailableSchoolResponse.from(schoolResponse, currentQuantity);
    })
    .toList();
🤖 Prompt for AI Agents
In src/main/java/life/mosu/mosuserver/application/school/SchoolService.java
around lines 25 to 32, the current code calls the cache manager individually for
each school without error handling, causing potential failures and performance
issues due to N+1 calls, and lacks null handling for currentQuantity. Refactor
to first collect all school names, then perform a batch cache call to get
application counts in one operation, handle any exceptions from the cache
manager gracefully, and use getOrDefault to assign zero when currentQuantity is
null before mapping to AvailableSchoolResponse.

.toList();
Comment on lines 23 to 33

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This implementation has a performance issue known as the N+1 problem. It iterates through all schools and makes a separate call to Redis for each school inside the map function. This can lead to a large number of network requests and slow down the API response, especially as the number of schools grows.

To optimize this, you should fetch all school application counts in a single batch request.

Here's a suggested approach:

  1. Fetch all schools from the repository.
  2. Collect all school names.
  3. Make a single batch call to SchoolQuotaCacheManager to get all counts (this would require adding a new method to SchoolQuotaCacheManager that accepts a list of school names and uses Redis' MGET command).
  4. Create a map of school names to their application counts.
  5. Stream over the schools list and use the map to look up the count for each school.

Example implementation:

public List<AvailableSchoolResponse> getAvailableSchools() {
    List<SchoolJpaEntity> schools = schoolJpaRepository.findAll();
    List<String> schoolNames = schools.stream()
            .map(SchoolJpaEntity::getSchoolName)
            .toList();

    // This method would need to be implemented in SchoolQuotaCacheManager
    // to perform a batch fetch from Redis.
    Map<String, Long> applicationCounts = schoolQuotaCacheManager.getSchoolApplicationCountsInBatch(schoolNames);

    return schools.stream()
            .map(school -> {
                SchoolResponse schoolResponse = SchoolResponse.from(school);
                Long currentQuantity = applicationCounts.getOrDefault(school.getSchoolName(), 0L);
                return AvailableSchoolResponse.from(schoolResponse, currentQuantity);
            })
            .toList();
}

This change will significantly improve the performance of this endpoint.

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public interface SchoolJpaRepository extends JpaRepository<SchoolJpaEntity, Long
SELECT new life.mosu.mosuserver.domain.school.SchoolApplicationProjection(s.id, s.schoolName, COUNT(a))
FROM SchoolJpaEntity s
LEFT JOIN ApplicationSchoolJpaEntity a ON a.schoolId = s.id
LEFT JOIN PaymentJpaEntity p ON p.applicationSchoolId = a.id
WHERE p.paymentStatus = 'DONE'
Comment on lines +15 to +16
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix query logic to include schools with zero paid applications.

The current WHERE clause will exclude schools that have no applications with successful payments from the result set entirely. This is likely incorrect behavior - schools with 0 paid applications should still appear in the results with a count of 0.

Move the payment status condition to the JOIN clause to preserve schools with zero paid applications:

-                LEFT JOIN PaymentJpaEntity p ON p.applicationSchoolId = a.id
-                WHERE p.paymentStatus = 'DONE'
+                LEFT JOIN PaymentJpaEntity p ON p.applicationSchoolId = a.id AND p.paymentStatus = 'DONE'

This ensures all schools are included in the results, with accurate counts of only successfully paid applications.

🤖 Prompt for AI Agents
In src/main/java/life/mosu/mosuserver/domain/school/SchoolJpaRepository.java
around lines 15 to 16, the WHERE clause filtering on p.paymentStatus = 'DONE'
excludes schools without paid applications. To fix this, move the paymentStatus
= 'DONE' condition from the WHERE clause into the LEFT JOIN condition itself.
This change will preserve all schools in the results, including those with zero
paid applications, while still counting only successfully paid applications.

GROUP BY s.id, s.schoolName
""")
List<SchoolApplicationProjection> countBySchoolNameGroupBy();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import jakarta.annotation.PostConstruct;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import life.mosu.mosuserver.domain.application.ApplicationJpaEntity;
import life.mosu.mosuserver.domain.application.ApplicationJpaRepository;
import life.mosu.mosuserver.domain.application.Lunch;
Expand All @@ -23,6 +25,11 @@
import life.mosu.mosuserver.domain.inquiryAnswer.InquiryAnswerJpaRepository;
import life.mosu.mosuserver.domain.notice.NoticeJpaEntity;
import life.mosu.mosuserver.domain.notice.NoticeJpaRepository;
import life.mosu.mosuserver.domain.payment.PaymentAmountVO;
import life.mosu.mosuserver.domain.payment.PaymentJpaEntity;
import life.mosu.mosuserver.domain.payment.PaymentMethod;
import life.mosu.mosuserver.domain.payment.PaymentRepository;
import life.mosu.mosuserver.domain.payment.PaymentStatus;
import life.mosu.mosuserver.domain.profile.Education;
import life.mosu.mosuserver.domain.profile.Gender;
import life.mosu.mosuserver.domain.profile.Grade;
Expand Down Expand Up @@ -55,6 +62,7 @@ public class DatabaseInitializer {
private final NoticeJpaRepository noticeJpaRepository;
private final InquiryAnswerJpaRepository inquiryAnswerJpaRepository;
private final EventJpaRepository eventRepository;
private final PaymentRepository paymentRepository;
private final PasswordEncoder passwordEncoder;

@PostConstruct
Expand All @@ -69,7 +77,9 @@ public void init() {

List<UserJpaEntity> createdUsers = initializeUsersAndProfiles(random);
List<SchoolJpaEntity> createdSchools = initializeSchools();
initializeApplications(createdUsers, createdSchools, random);
List<ApplicationSchoolJpaEntity> createdAppSchools = initializeApplications(createdUsers,
createdSchools, random);
initializePayments(createdAppSchools);
initializeBoardItems(createdUsers, random);

log.info("모든 더미 데이터 초기화가 완료되었습니다.");
Expand Down Expand Up @@ -115,41 +125,75 @@ private List<UserJpaEntity> initializeUsersAndProfiles(Random random) {
private List<SchoolJpaEntity> initializeSchools() {
List<SchoolJpaEntity> schools = new ArrayList<>(List.of(
SchoolJpaEntity.builder()
.schoolName("모수고등학교")
.schoolName("대치중학교")
.area(Area.DAECHI)
.address(new AddressJpaVO("06164", "서울특별시", "강남구 테헤란로 123"))
.examDate(LocalDate.of(2025, 11, 20))
.capacity(300L)
.address(new AddressJpaVO("06234", "서울특별시", "강남구 대치동 987"))
.examDate(LocalDate.of(2025, 10, 19))
.capacity(532L)
.deadlineTime(LocalDateTime.of(2025, 10, 10, 23, 59))
.lunch(Lunch.OPTION1)
.lunchPrice(12000)
.build(),
SchoolJpaEntity.builder()
.schoolName("대치고등학교")
.area(Area.DAECHI)
.address(new AddressJpaVO("06283", "서울특별시", "강남구 대치동 학원가 100"))
.examDate(LocalDate.of(2025, 12, 5))
.capacity(150L)
.schoolName("목운중학교")
.area(Area.MOKDONG)
.address(new AddressJpaVO("07995", "서울특별시", "양천구 목동서로 369"))
.examDate(LocalDate.of(2025, 10, 26))
.capacity(896L)
.deadlineTime(LocalDateTime.of(2025, 10, 17, 23, 59))
.lunch(Lunch.OPTION1)
.lunchPrice(12000)
.build(),
SchoolJpaEntity.builder()
.schoolName("신서중학교")
.area(Area.MOKDONG)
.address(new AddressJpaVO("08018", "서울특별시", "양천구 신정로 250"))
.examDate(LocalDate.of(2025, 11, 2))
.capacity(896L)
.deadlineTime(LocalDateTime.of(2025, 10, 24, 23, 59))
.lunch(Lunch.OPTION2)
.lunchPrice(13000)
.build(),
SchoolJpaEntity.builder()
.schoolName("부산명문고")
.schoolName("개원중학교")
.area(Area.DAECHI)
.address(new AddressJpaVO("48057", "부산광역시", "해운대구 센텀시티로 50"))
.examDate(LocalDate.of(2025, 11, 25))
.capacity(250L)
.address(new AddressJpaVO("06327", "서울특별시", "강남구 개포로 619"))
.examDate(LocalDate.of(2025, 10, 26))
.capacity(840L)
.deadlineTime(LocalDateTime.of(2025, 10, 17, 23, 59))
.lunch(Lunch.OPTION1)
.lunchPrice(12000)
.build(),
SchoolJpaEntity.builder()
.schoolName("문래중학교")
.area(Area.MOKDONG)
.address(new AddressJpaVO("07291", "서울특별시", "영등포구 문래로 195"))
.examDate(LocalDate.of(2025, 10, 19))
.capacity(558L)
.deadlineTime(LocalDateTime.of(2025, 10, 10, 23, 59))
.lunch(Lunch.OPTION2)
.lunchPrice(13000)
.build(),
SchoolJpaEntity.builder()
.schoolName("노원스터디센터")
.schoolName("온곡중학교")
.area(Area.NOWON)
.address(new AddressJpaVO("01777", "서울특별시", "노원구 동일로 1400"))
.examDate(LocalDate.of(2026, 1, 10))
.capacity(80L)
.address(new AddressJpaVO("01673", "서울특별시", "노원구 덕릉로 70길 99"))
.examDate(LocalDate.of(2025, 10, 19))
.capacity(448L)
.deadlineTime(LocalDateTime.of(2025, 10, 10, 23, 59))
.lunch(Lunch.OPTION1)
.lunchPrice(12000)
.build()
));
schoolRepository.saveAll(schools);
log.info("School 데이터 {}건 생성 완료.", schools.size());
return schools;
}

private void initializeApplications(List<UserJpaEntity> users, List<SchoolJpaEntity> schools,
private List<ApplicationSchoolJpaEntity> initializeApplications(List<UserJpaEntity> users,
List<SchoolJpaEntity> schools,
Random random) {
List<ApplicationSchoolJpaEntity> createdAppSchools = new ArrayList<>();
for (int i = 0; i < users.size(); i++) {
UserJpaEntity user = users.get(i);
ApplicationJpaEntity application = applicationRepository.save(
Expand All @@ -172,7 +216,7 @@ private void initializeApplications(List<UserJpaEntity> users, List<SchoolJpaEnt
subjects.add(Subject.values()[random.nextInt(Subject.values().length)]);
}

applicationSchoolRepository.save(
ApplicationSchoolJpaEntity appSchool = applicationSchoolRepository.save(
ApplicationSchoolJpaEntity.builder()
.userId(user.getId())
.applicationId(application.getId())
Expand All @@ -187,9 +231,52 @@ private void initializeApplications(List<UserJpaEntity> users, List<SchoolJpaEnt
.subjects(subjects)
.build()
);
createdAppSchools.add(appSchool);
}
}
log.info("Application 및 ApplicationSchool 데이터 생성 완료.");
return createdAppSchools;
}

private void initializePayments(List<ApplicationSchoolJpaEntity> applicationSchools) {
List<PaymentJpaEntity> payments = new ArrayList<>();
int successCount = applicationSchools.size() / 2;

for (int i = 0; i < applicationSchools.size(); i++) {
ApplicationSchoolJpaEntity appSchool = applicationSchools.get(i);
String orderId = "order-" + UUID.randomUUID().toString().substring(0, 8);

if (i < successCount) {
PaymentAmountVO paymentAmount = PaymentAmountVO.of(
12000,
10909,
1091,
12000,
0
);

PaymentJpaEntity payment = PaymentJpaEntity.of(
appSchool.getId(),
"pkey-" + UUID.randomUUID().toString().substring(0, 12),
orderId,
PaymentStatus.DONE,
paymentAmount,
PaymentMethod.CARD
);
payments.add(payment);
} else {
PaymentJpaEntity payment = PaymentJpaEntity.ofFailure(
appSchool.getId(),
orderId,
PaymentStatus.ABORTED,
12000
);
payments.add(payment);
}
}
paymentRepository.saveAll(payments);
log.info("Payment 데이터 {}건 생성 완료 (성공: {}, 실패: {}).", payments.size(), successCount,
payments.size() - successCount);
}

private void initializeBoardItems(List<UserJpaEntity> users, Random random) {
Expand Down Expand Up @@ -241,4 +328,4 @@ private void initializeBoardItems(List<UserJpaEntity> users, Random random) {
}
log.info("Board(Notice, Inquiry, Event) 데이터 생성 완료.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import java.util.List;
import life.mosu.mosuserver.application.school.SchoolService;
import life.mosu.mosuserver.global.util.ApiResponseWrapper;
import life.mosu.mosuserver.presentation.school.dto.AvailableSchoolResponse;
import life.mosu.mosuserver.presentation.school.dto.SchoolRegistrationRequest;
import life.mosu.mosuserver.presentation.school.dto.SchoolResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand All @@ -31,9 +31,9 @@ public ResponseEntity<ApiResponseWrapper<Void>> create(
}

@GetMapping
public ResponseEntity<ApiResponseWrapper<List<SchoolResponse>>> getSchools() {
public ResponseEntity<ApiResponseWrapper<List<AvailableSchoolResponse>>> getSchools() {

List<SchoolResponse> schools = schoolService.getSchools();
List<AvailableSchoolResponse> schools = schoolService.getAvailableSchools();

return ResponseEntity.ok(ApiResponseWrapper.success(HttpStatus.OK, "학교 조회 성공", schools));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import life.mosu.mosuserver.global.util.ApiResponseWrapper;
import life.mosu.mosuserver.presentation.school.dto.AvailableSchoolResponse;
import life.mosu.mosuserver.presentation.school.dto.SchoolRegistrationRequest;
import life.mosu.mosuserver.presentation.school.dto.SchoolResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;

Expand All @@ -19,17 +19,15 @@ public interface SchoolControllerDocs {

@Operation(summary = "[관리자] 학교 정보 등록", description = "새로운 학교 정보를 시스템에 등록합니다. 인가 추가 예정")
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "학교 등록 성공"),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터"),
@ApiResponse(responseCode = "409", description = "이미 존재하는 학교 정보")
@ApiResponse(responseCode = "201", description = "학교 등록 성공")
})
ResponseEntity<ApiResponseWrapper<Void>> create(@RequestBody SchoolRegistrationRequest request);

@Operation(summary = "[사용자] 전체 학교 목록 조회", description = "시스템에 등록된 모든 학교 목록을 조회합니다. 인가 추가 예정")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "학교 목록 조회 성공",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = SchoolResponse.class)))),
content = @Content(array = @ArraySchema(schema = @Schema(implementation = AvailableSchoolResponse.class)))),
@ApiResponse(responseCode = "500", description = "서버 내부 오류")
})
ResponseEntity<ApiResponseWrapper<List<SchoolResponse>>> getSchools();
ResponseEntity<ApiResponseWrapper<List<AvailableSchoolResponse>>> getSchools();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package life.mosu.mosuserver.presentation.school.dto;

import java.time.LocalDate;
import java.time.LocalDateTime;

public record AvailableSchoolResponse(
Long id,
String schoolName,
String area,
String lunch,
Integer lunchPrice,
LocalDateTime deadlineTime,
LocalDate examDate,
Long currentQuantity,
Long capacity
) {

public static AvailableSchoolResponse from(
SchoolResponse school,
Long currentQuantity
) {
return new AvailableSchoolResponse(
school.id(),
school.schoolName(),
school.area(),
school.lunch(),
school.lunchPrice(),
school.deadlineTime(),
school.examDate(),
currentQuantity,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The schoolQuotaCacheManager.getSchoolApplicationCounts() method can return null if a school has no applications yet and its count is not in the cache. This will result in currentQuantity being null in the API response, which can be problematic for clients.

It's better to treat a missing count as zero. You can ensure currentQuantity is never null by providing a default value here.

Suggested change
currentQuantity,
currentQuantity != null ? currentQuantity : 0L,

school.capacity()
);
}

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package life.mosu.mosuserver.presentation.school.dto;

import java.time.LocalDate;
import java.time.LocalDateTime;
import life.mosu.mosuserver.domain.school.SchoolJpaEntity;
import life.mosu.mosuserver.presentation.common.AddressResponse;

public record SchoolResponse(
Long id,
String schoolName,
String area,
AddressResponse address,
String lunch,
Integer lunchPrice,
LocalDateTime deadlineTime,
LocalDate examDate,
Long capacity
) {
Expand All @@ -17,8 +19,10 @@ public static SchoolResponse from(SchoolJpaEntity school) {
return new SchoolResponse(
school.getId(),
school.getSchoolName(),
school.getArea().name(),
AddressResponse.from(school.getAddress()),
school.getArea().getAreaName(),
school.getLunch().getLunchName(),
school.getLunchPrice(),
school.getDeadlineTime(),
school.getExamDate(),
school.getCapacity()
);
Expand Down