-
Notifications
You must be signed in to change notification settings - Fork 0
Feat: [FN-297] 그룹 생성 API 구현 #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Walkthrough그룹 생성 기능을 추가했습니다. 도메인 모델, 포트·어댑터, JPA 엔티티·리포지토리, 애플리케이션 서비스, 웹 컨트롤러와 JPA 감사 설정 및 빌드(프로토콜 버퍼·gRPC·QueryDSL) 구성이 포함됩니다. Changes
Sequence Diagram(s)sequenceDiagram
actor User as User
participant Controller as GroupController
participant Service as CreateGroupService
participant GroupPort as GroupRepositoryPort
participant MemberPort as GroupMemberRepositoryPort
participant DB as Database
rect rgba(200,200,255,0.5)
User->>Controller: POST /v1/groups (body + X-USER-ID)
Controller->>Service: create(CreateGroupCommand, userId)
end
rect rgba(200,255,200,0.5)
Service->>Service: Group.create(cmd) (유효성 검사)
Service->>GroupPort: saveNewGroup(domainGroup)
GroupPort->>DB: INSERT app_groups
DB-->>GroupPort: generated groupId
GroupPort-->>Service: groupId
Service->>MemberPort: saveOwner(groupId, userId)
MemberPort->>DB: INSERT group_members (role=OWNER)
DB-->>MemberPort: 저장 완료
MemberPort-->>Service: void
end
rect rgba(255,200,200,0.5)
Service-->>Controller: CreateGroupResult(groupId)
Controller-->>User: 200 OK (CreateGroupResponseDto)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 11
🤖 Fix all issues with AI agents
In `@build.gradle`:
- Line 15: build.gradle의 설정에서 description = 'Image'로 잘못 설정되어 있습니다; 이 프로젝트는 그룹
서비스이므로 description 값을 'Group' 또는 PR/README에 맞는 적절한 설명으로 변경하세요 (찾을 식별자:
description = 'Image'를 찾아 description 값을 업데이트). 변경 후 커밋 메시지에 "fix: correct
project description" 등으로 기록하세요.
- Around line 67-71: The current configuration sets
options.generatedSourceOutputDirectory for all JavaCompile tasks (via
tasks.withType(JavaCompile).configureEach), which affects test compilation;
restrict this to the main compile task by setting
options.generatedSourceOutputDirectory only for the compileJava task (use the
compileJava task's options and querydslDir) so that querydslDir is applied to
compileJava only and not to testCompile or other JavaCompile tasks.
- Around line 39-65: The dependencies block in build.gradle is missing the
standard Spring Boot test starter; add testImplementation
'org.springframework.boot:spring-boot-starter-test' inside the dependencies { }
section (alongside existing testImplementation/testRuntimeOnly entries) so JUnit
5, Mockito and Spring Test utilities are available for unit/integration tests;
ensure it is added as testImplementation (not testRuntimeOnly) to work with the
current test dependencies like
'org.springframework.boot:spring-boot-starter-data-redis-test'.
- Line 50: Remove the obsolete javax.annotation dependency declaration
implementation 'javax.annotation:javax.annotation-api:1.3.2' from build.gradle
because Spring Boot 4 uses Jakarta EE; instead rely on the existing
jakarta.annotation:jakarta.annotation-api already configured for annotation
processing (referenced elsewhere in this file). Delete the implementation line
for javax.annotation, run a quick build to verify no compile errors, and ensure
all annotation-processing and imports resolve to jakarta.annotation types.
- Around line 78-94: The protobuf configuration currently hardcodes protoc and
grpc plugin artifacts in the protobuf block (artifact =
"com.google.protobuf:protoc:3.25.3" and "io.grpc:protoc-gen-grpc-java:1.64.0"),
causing a mismatch with the Spring gRPC BOM-managed versions (protoc 4.33.2 and
protoc-gen-grpc-java 1.77.1); fix by either removing the explicit version
pinning so the BOM controls versions or update those artifact strings to the BOM
versions (protoc -> com.google.protobuf:protoc:4.33.2 and protoc-gen-grpc-java
-> io.grpc:protoc-gen-grpc-java:1.77.1) in the protobuf { protoc { artifact } }
and plugins { grpc { artifact } } entries to ensure generated code and runtime
libs (grpc-stub, protobuf-java) remain consistent.
In `@src/main/java/flipnote/group/adapter/out/entity/GroupEntity.java`:
- Line 3: GroupEntity currently imports CreateGroupCommand which is unused and
violates dependency direction; remove the unused import statement for
CreateGroupCommand from GroupEntity and ensure the persistence entity does not
reference any application port types (replace any usage with entity/DTO classes
or mapping logic inside application/service layers if present); verify there are
no remaining references to CreateGroupCommand inside the GroupEntity class or
its methods and move any transformation logic that depends on application-layer
types into the appropriate application/service mapper.
In `@src/main/java/flipnote/group/adapter/out/entity/GroupMemberEntity.java`:
- Around line 21-31: GroupMemberEntity's DB-level unique constraint
(uk_group_members_group_user on group_members for (group_id,user_id)) conflicts
with BaseEntity soft-delete semantics and will cause unique violations on
rejoin; fix by either: 1) remove the JPA UniqueConstraint and add a PostgreSQL
partial unique index via migration (name it uk_group_members_group_user) on
(group_id, user_id) WHERE deleted_at IS NULL; or 2) implement a restore flow in
the repository/service that finds a soft-deleted GroupMemberEntity and calls its
restore() on rejoin instead of inserting a new row (adjust createMember logic to
check BaseEntity.deleted_at); or 3) change GroupMemberEntity's deletion behavior
to hard-delete by overriding BaseEntity soft-delete behavior for this entity —
choose one approach and apply the corresponding schema migration or
repository/service change.
In `@src/main/java/flipnote/group/api/dto/request/CreateGroupRequestDto.java`:
- Line 12: The CreateGroupRequestDto's name field lacks a max-length constraint
and can exceed GroupEntity.name (length = 50); add a DTO-level validation by
annotating the name field in CreateGroupRequestDto with `@Size`(max = 50) and
import jakarta.validation.constraints.Size so validation fails with a clear
error before hitting the DB.
In `@src/main/java/flipnote/group/application/port/out/GroupRepositoryPort.java`:
- Around line 1-8: The port interface GroupRepositoryPort currently depends on
the adapter entity GroupEntity and imports an unused CreateGroupCommand; change
the port to accept/use the domain Group model (e.g., replace GroupEntity
parameter with your domain model type, e.g., Group) so application.port.out
depends only on domain types, remove the unused CreateGroupCommand import, and
perform the entity↔domain mapping inside the adapter implementation (e.g.,
GroupRepositoryAdapter) when implementing saveNewGroup.
In `@src/main/java/flipnote/group/application/service/CreateGroupService.java`:
- Line 6: Change the port to accept the domain object instead of a persistence
entity: update GroupRepositoryPort.saveNewGroup to take a domain Group and
return Long, then move the mapping logic into the adapter by implementing
GroupRepositoryAdapter.saveNewGroup to call GroupMapper.createNewEntity(group)
and persist the resulting GroupEntity; finally remove the adapter import from
CreateGroupService (stop using GroupMapper there) and call the updated
GroupRepositoryPort.saveNewGroup(domainGroup) instead. Ensure method signatures
for GroupRepositoryPort.saveNewGroup, GroupRepositoryAdapter.saveNewGroup,
GroupMapper.createNewEntity, and usages in CreateGroupService are updated
consistently.
In `@src/main/java/flipnote/group/domain/model/group/Group.java`:
- Around line 90-109: The validate(CreateGroupCommand cmd) method is missing a
length check for cmd.name(), which can exceed the GroupEntity name column max
length (50) and cause DB exceptions; add a check in validate to ensure
cmd.name().length() <= 50 (or use a constant) and throw an
IllegalArgumentException (e.g., "name too long") when it exceeds that limit so
invalid input is rejected at the domain layer before persistence.
🧹 Nitpick comments (13)
src/main/java/flipnote/group/domain/model/group/Category.java (1)
6-15: 유효하지 않은 카테고리 값에 대해null반환 대신 예외를 던지는 것을 고려해 주세요.
null/빈 문자열이 아닌데 매칭되는 enum 상수가 없는 경우는 클라이언트의 잘못된 입력일 가능성이 높습니다.null을 반환하면 호출부에서 NPE가 발생할 수 있습니다. 카테고리가 선택(optional) 필드라면null/빈 문자열에 대한null반환은 괜찮지만, 유효하지 않은 값에 대해서는IllegalArgumentException을 던지는 것이 안전합니다.♻️ 제안하는 수정안
public static Category from(String category) { if (category == null || category.isEmpty()) { return null; } try { return Category.valueOf(category); } catch (IllegalArgumentException e) { - return null; + throw new IllegalArgumentException("Invalid category: " + category); } }src/main/java/flipnote/group/infrastructure/config/AuditingConfig.java (1)
6-13: 빈 Javadoc 블록 제거 권장Lines 6-8의 빈 Javadoc 주석(
/** */)은 의미 없는 코드 노이즈입니다. 제거하거나 클래스 목적을 설명하는 내용을 추가해 주세요.♻️ 제안
-/** - * - */ `@EnableJpaAuditing` `@Configuration` public class AuditingConfig {src/main/java/flipnote/group/domain/model/BaseEntity.java (1)
14-49: Soft-delete 필터링 전략 확인 필요
BaseEntity에 soft-delete 메커니즘이 잘 구현되어 있습니다. 다만, 이를 상속하는 엔티티(GroupEntity,GroupMemberEntity)에@Where(clause = "deleted_at IS NULL")또는 Hibernate 6의@SQLRestriction같은 자동 필터링이 적용되어 있지 않습니다. 별도의 쿼리 조건 없이 조회하면 삭제된 레코드도 함께 반환될 수 있으므로, 향후 조회 로직에서 이를 고려해 주세요.src/main/java/flipnote/group/application/port/out/GroupMemberRepositoryPort.java (1)
1-7: 사용되지 않는 import 제거Line 3의
GroupMemberRoleimport가 인터페이스 내에서 사용되지 않습니다. 제거해 주세요.♻️ 제안
package flipnote.group.application.port.out; -import flipnote.group.domain.model.member.GroupMemberRole; - public interface GroupMemberRepositoryPort { void saveOwner(Long groupId, Long userId); }src/main/java/flipnote/group/adapter/out/persistence/mapper/GroupMemberMapper.java (1)
10-19:GroupMemberEntity.createOwner와 중복되는 로직입니다.
GroupMemberEntity(관련 스니펫 참조)에 이미 동일한createOwner(Long groupId, Long userId)정적 팩토리 메서드가 존재합니다. 이 매퍼는 해당 로직을 그대로 복제하고 있어 불필요합니다.GroupMemberRepositoryAdapter에서GroupMemberEntity.createOwner(groupId, userId)를 직접 호출하면 이 클래스를 제거할 수 있습니다.또한, 정적 메서드만 있는 유틸리티 클래스에
@Component를 붙이면 불필요한 Spring 빈이 등록됩니다.GroupMapper도 동일한 패턴을 사용하고 있으니 함께 정리하는 것을 권장합니다.src/main/java/flipnote/group/domain/model/member/GroupMember.java (1)
10-11: 도메인 모델에@Setter는 캡슐화를 약화시킵니다.
GroupMember는 도메인 모델로서 불변성을 보장해야 합니다.@Setter를 제거하고, 상태 변경이 필요하다면 의미 있는 도메인 메서드(예:changeRole(GroupMemberRole newRole))를 통해 제어하는 것이 좋습니다. 팩토리 메서드(createOwner,join)를 통한 생성 패턴은 적절하므로, setter 없이도 충분히 동작합니다.♻️ `@Setter` 제거 제안
`@Getter` -@Setter `@NoArgsConstructor`(access = AccessLevel.PRIVATE) public class GroupMember {src/main/java/flipnote/group/adapter/in/web/GroupController.java (1)
30-47: 리소스 생성 시 HTTP 201 (Created) 응답이 더 적절합니다.POST로 그룹을 생성하는 엔드포인트이므로
ResponseEntity.ok()(200) 대신ResponseEntity.status(HttpStatus.CREATED).body(res)또는ResponseEntity.created(uri).body(res)를 사용하는 것이 REST 규약에 부합합니다.♻️ 수정 제안
- return ResponseEntity.ok(res); + return ResponseEntity.status(HttpStatus.CREATED).body(res);src/main/java/flipnote/group/adapter/out/persistence/mapper/GroupMapper.java (1)
10-12:@Component는 정적 메서드만 있는 유틸리티 클래스에 불필요합니다.
createNewEntity가static메서드이므로 Spring 빈으로 등록할 필요가 없습니다.GroupMemberMapper도 동일한 패턴을 따르고 있으니, 둘 다@Component를 제거하고 순수 유틸리티 클래스로 사용하는 것을 권장합니다.♻️ 제안
-@Component `@NoArgsConstructor`(access = AccessLevel.PRIVATE) public class GroupMapper {src/main/java/flipnote/group/domain/model/group/Group.java (3)
3-3: 도메인 모델이 애플리케이션 포트에 의존하고 있습니다.
Group도메인 모델이CreateGroupCommand(application port)를 직접 임포트하면 헥사고날 아키텍처의 의존성 방향 원칙에 위배됩니다. 도메인 계층은 가장 안쪽 계층으로, 외부 계층(application)에 의존하면 안 됩니다.create()메서드가 개별 파라미터를 받거나, 도메인 계층에 정의된 인터페이스/VO를 사용하도록 변경하는 것을 권장합니다.
10-12: 도메인 모델에@Setter를 사용하면 불변성이 깨집니다.
@Setter가 클래스 전체에 적용되어id,memberCount등 모든 필드가 외부에서 자유롭게 변경 가능합니다. 도메인 모델의 상태 변경은 의미 있는 도메인 메서드를 통해서만 이루어지는 것이 바람직합니다.@Setter를 제거하고 필요한 상태 변경만 명시적 메서드로 노출하는 것을 권장합니다.
5-5: 사용되지 않는 import:lombok.Builder
Group클래스에@Builder어노테이션이 사용되지 않으므로 이 import를 제거해 주세요.♻️ 제안
-import lombok.Builder;build.gradle (2)
61-64: QueryDSL 버전(5.0.0)이 하드코딩되어 있습니다. 버전 변수를 사용하거나 BOM 관리를 권장합니다.여러 곳에서 동일 버전을 반복 기재하면 업그레이드 시 불일치가 발생할 수 있습니다.
♻️ 버전 변수 추출 제안
ext { springGrpcVersion = "1.0.1" + querydslVersion = "5.0.0" }- implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' - annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" + implementation "com.querydsl:querydsl-jpa:${querydslVersion}:jakarta" + annotationProcessor "com.querydsl:querydsl-apt:${querydslVersion}:jakarta"
96-105:$buildDir는 Gradle 8+에서 deprecated입니다.layout.buildDirectory를 사용하세요.Line 67에서는
layout.buildDirectory를 올바르게 사용하고 있지만, 여기서는 deprecated된$buildDir를 사용하고 있어 일관성이 없습니다. Gradle 9에서는$buildDir가 제거될 예정입니다.♻️ 수정 제안
sourceSets { main { java { srcDirs += [ - "$buildDir/generated/sources/proto/main/java", - "$buildDir/generated/sources/proto/main/grpc" + layout.buildDirectory.dir("generated/sources/proto/main/java").get().asFile, + layout.buildDirectory.dir("generated/sources/proto/main/grpc").get().asFile ] } } }
| @Table( | ||
| name = "group_members", | ||
| uniqueConstraints = { | ||
| @UniqueConstraint( | ||
| name = "uk_group_members_group_user", | ||
| columnNames = {"group_id", "user_id"} | ||
| ) | ||
| } | ||
| ) | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| public class GroupMemberEntity extends BaseEntity { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Soft-delete와 unique constraint 간 충돌 가능성
(group_id, user_id)에 대한 unique constraint가 설정되어 있으나, BaseEntity의 soft-delete 패턴을 사용하면 탈퇴(soft-deleted) 후 재가입 시 DB 레벨에서 unique constraint violation이 발생할 수 있습니다.
해결 방안으로는:
- Unique constraint에
deleted_at IS NULLpartial index 적용 (PostgreSQL 지원) - 재가입 시 soft-deleted 레코드를
restore()하여 재사용 - Hard delete로 전환
향후 멤버 탈퇴/재가입 플로우 구현 시 반드시 고려해 주세요.
🤖 Prompt for AI Agents
In `@src/main/java/flipnote/group/adapter/out/entity/GroupMemberEntity.java`
around lines 21 - 31, GroupMemberEntity's DB-level unique constraint
(uk_group_members_group_user on group_members for (group_id,user_id)) conflicts
with BaseEntity soft-delete semantics and will cause unique violations on
rejoin; fix by either: 1) remove the JPA UniqueConstraint and add a PostgreSQL
partial unique index via migration (name it uk_group_members_group_user) on
(group_id, user_id) WHERE deleted_at IS NULL; or 2) implement a restore flow in
the repository/service that finds a soft-deleted GroupMemberEntity and calls its
restore() on rejoin instead of inserting a new row (adjust createMember logic to
check BaseEntity.deleted_at); or 3) change GroupMemberEntity's deletion behavior
to hard-delete by overriding BaseEntity soft-delete behavior for this entity —
choose one approach and apply the corresponding schema migration or
repository/service change.
src/main/java/flipnote/group/api/dto/request/CreateGroupRequestDto.java
Outdated
Show resolved
Hide resolved
src/main/java/flipnote/group/application/port/out/GroupRepositoryPort.java
Show resolved
Hide resolved
src/main/java/flipnote/group/application/service/CreateGroupService.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@build.gradle`:
- Around line 61-64: Update the QueryDSL dependency declarations to let the BOM
manage the version or explicitly set it to 5.1.0+: remove the hardcoded
"5.0.0:jakarta" from implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
and annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" (or change
both to 5.1.0 or later) so Spring Boot 4's BOM (which expects 5.1.0) is not
overridden; also replace any usage of the deprecated $buildDir (lines referenced
around $buildDir) with layout.buildDirectory to be compatible with Gradle 8+ and
future Gradle 10 removal.
🧹 Nitpick comments (1)
build.gradle (1)
96-105:$buildDir는 Gradle 8+에서 deprecated되었습니다.layout.buildDirectory를 사용하세요.Line 67에서 이미
layout.buildDirectory를 사용하고 있으므로 일관성을 위해 여기서도 동일한 API를 사용하는 것이 좋습니다.♻️ 수정 제안
sourceSets { main { java { srcDirs += [ - "$buildDir/generated/sources/proto/main/java", - "$buildDir/generated/sources/proto/main/grpc" + layout.buildDirectory.dir("generated/sources/proto/main/java").get().asFile, + layout.buildDirectory.dir("generated/sources/proto/main/grpc").get().asFile ] } } }
| implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' | ||
| annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" | ||
| annotationProcessor "jakarta.annotation:jakarta.annotation-api" | ||
| annotationProcessor "jakarta.persistence:jakarta.persistence-api" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if there's actual QueryDSL usage in the codebase
echo "=== QueryDSL usage in Java files ==="
rg -n 'querydsl|JPAQueryFactory|QClass|BooleanBuilder|@QueryEntity' --type java 2>/dev/null | head -30
echo ""
echo "=== Check full build.gradle to understand context ==="
wc -l build.gradle
echo ""
echo "=== Check Spring Boot version and toolchain ==="
rg -n 'spring-boot-gradle-plugin|SpringBootPlugin|sourceCompatibility|targetCompatibility|toolchain' build.gradleRepository: FlipNoteTeam/FlipNote-Group
Length of output: 244
🌐 Web query:
QueryDSL 5.0.0 Spring Boot 4 compatibility Hibernate 7 Jakarta EE
💡 Result:
- Spring Boot 4 baseline (JPA/Hibernate/Jakarta): Boot 4.0 upgrades to Jakarta Persistence 3.2 and Hibernate ORM 7.1 (Jakarta EE 11 level). [1] Spring Framework 7 (the foundation for Boot 4) also states a Jakarta EE 11 baseline (incl. Hibernate ORM 7). [2]
- QueryDSL 5.0.0 + Jakarta EE: QueryDSL 5.x supports Jakarta namespaces via the
jakartaclassifier (e.g.,querydsl-jpa:…:jakarta,querydsl-apt:…:jakarta). [3] - Hibernate 7 compatibility risk: QueryDSL’s Hibernate-specific integration (
com.querydsl.jpa.hibernate.*) depends on Hibernate native APIs (e.g.,ScrollableResults) and has known breakages already with Hibernate 6.x that were closed as “wontfix” for QueryDSL 5.0.0-era usage. [4] With Boot 4 moving to Hibernate 7.1 [1], you should assume Hibernate-specific QueryDSL features may break unless proven in your test suite. - Practical recommendation:
- Prefer pure JPA QueryDSL usage (EntityManager-based) and avoid Hibernate-only QueryDSL APIs if you want the best chance of working on Boot 4/Hibernate 7.1.
- Don’t stick to 5.0.0—QueryDSL 5.1.0 exists (latest tag) and is the safer starting point for any modern stack testing. [5]
Sources: Spring Boot 4.0 release notes [1], Spring Framework 7 baseline announcement [2], QueryDSL Jakarta classifier guidance [3], QueryDSL Hibernate 6.x incompatibility issue example [4], QueryDSL releases (5.1.0) [5].
🌐 Web query:
spring-boot-starter-data-redis-test Maven artifact
💡 Result:
Maven coordinates
- GroupId:
org.springframework.boot - ArtifactId:
spring-boot-starter-data-redis-test - What it is: Starter for testing Redis with Spring Data Redis (Lettuce). [1]
Latest versions in Maven Central (as of Jan 22, 2026)
- Latest stable:
4.0.2[2] - Milestone:
4.1.0-M1[2]
Maven dependency (typical: test scope)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-test</artifactId>
<version>4.0.2</version>
<scope>test</scope>
</dependency>🌐 Web query:
QueryDSL version Spring Boot 4.0 recommended compatibility matrix
💡 Result:
Spring Boot 4.0.x → recommended QueryDSL version (compatibility)
| Spring Boot | Spring Data baseline | Recommended QueryDSL (managed by Boot BOM) |
|---|---|---|
| 4.0.x | Spring Data 2025.1 | QueryDSL 5.1.0 (via com.querydsl:querydsl-bom) (github.com) |
Notes
- Spring Data’s Querydsl integration is best-effort and mentions that the community has also forked Querydsl under OpenFeign (
io.github.openfeign.querydsl). (docs.spring.io) - If you use Spring Boot’s dependency management (
spring-boot-dependencies), you typically omit Querydsl versions and let Boot pin them (Boot 4.0.2 pinscom.querydsl:querydsl-bomto 5.1.0). (mvnrepository.com)
Citations:
- 1: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Release-Notes?utm_source=openai
- 2: https://docs.spring.io/spring-data/jpa/reference/repositories/core-extensions.html?utm_source=openai
- 3: https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies/4.0.2/dependencies
🏁 Script executed:
#!/bin/bash
echo "=== Lines 96-105 (sourceSets with $buildDir) ==="
sed -n '96,105p' build.gradle
echo ""
echo "=== Lines 57-58 (test starters) ==="
sed -n '55,65p' build.gradle
echo ""
echo "=== Check Gradle version ==="
if [ -f gradle/wrapper/gradle-wrapper.properties ]; then
rg 'distributionUrl' gradle/wrapper/gradle-wrapper.properties
fi
echo ""
echo "=== Check for deprecated buildDir usage ==="
rg '\$buildDir' build.gradleRepository: FlipNoteTeam/FlipNote-Group
Length of output: 1135
🌐 Web query:
Gradle $buildDir deprecated layout.buildDirectory when removed
💡 Result:
Project.buildDir(aFile) was deprecated in Gradle 8.x in favor of the lazyDirectoryPropertyproject.layout.buildDirectory. [1]- It has not been removed in Gradle 9.0.0 (the Gradle 9.0 upgrade guide lists many removals, but does not list
Project.buildDiras removed). [2] - The Gradle team is tracking its removal in gradle/gradle issue #25661: it was “tentatively scheduled for Gradle 9” in the issue text, but the issue is currently targeted at the 10.0.0 RC1 milestone—so removal is likely Gradle 10, not 9. [3]
Migration: use layout.buildDirectory (and .dir(...) / .file(...), or .fileValue(...) if you need to set it from a File). [1]
QueryDSL 5.0.0을 5.1.0으로 업그레이드하거나 버전을 명시하지 않아야 합니다.
Spring Boot 4.0의 BOM은 QueryDSL을 5.1.0으로 관리하지만, 빌드파일에서 명시적으로 5.0.0을 지정하면 이를 무시합니다. QueryDSL 5.0.0은 Hibernate 6.x 이상과의 호환성 문제가 있으며 "wontfix"로 표시되었고, Spring Boot 4가 사용하는 Hibernate 7.1과의 동작 보장이 불확실합니다.
두 가지 해결책:
- QueryDSL 의존성의 버전을 제거하여 BOM이 관리하도록 함 (권장)
- 명시적으로 5.1.0 이상으로 업그레이드
또한 lines 100-101의 $buildDir는 Gradle 8.x부터 deprecated되었습니다. Gradle 10에서 제거될 예정이므로 layout.buildDirectory로 변경하기를 권장합니다.
🤖 Prompt for AI Agents
In `@build.gradle` around lines 61 - 64, Update the QueryDSL dependency
declarations to let the BOM manage the version or explicitly set it to 5.1.0+:
remove the hardcoded "5.0.0:jakarta" from implementation
'com.querydsl:querydsl-jpa:5.0.0:jakarta' and annotationProcessor
"com.querydsl:querydsl-apt:5.0.0:jakarta" (or change both to 5.1.0 or later) so
Spring Boot 4's BOM (which expects 5.1.0) is not overridden; also replace any
usage of the deprecated $buildDir (lines referenced around $buildDir) with
layout.buildDirectory to be compatible with Gradle 8+ and future Gradle 10
removal.
Summary by CodeRabbit
릴리스 노트
새로운 기능
인프라 개선