25%
57,750원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
N + 1 문제 해결 fetch join 관련해서 질문드릴 것이 있습니다!
안녕하세요. 38강의 N + 1 문제를 해결하기 위한 fetch join 문제 해결과 관련해서 제가 발견(?)한 것을 질문드리고자 합니다!수업 내용 중 N + 1 문제를 querydsl을 사용해서 해결하는 것을 보여주셨는데요. 코드가 다음과 같았습니다.class UserRepositoryCustomImpl( private val queryFactory: JPAQueryFactory ) : UserRepositoryCustom { override fun findAllWithHistories(): List<User> { return queryFactory .select(user) .distinct() .from(user) .leftJoin(userLoanHistory).on(userLoanHistory.user.id.eq(user.id)).fetchJoin() .fetch() } }그러고 테스트를 돌렸을 때 쿼리가 찍히는 걸 보면 다음과 같습니다.N + 1 문제가 아직 발생하고 있는 것 같습니다.조금 이상해서 구글링을 해보니 querydsl에서 on 절을 사용하면 두 엔티티가 연관관계라는 것을 인식하지 못 한다고 하네요! 그래서 코드를 다음과 같이 좀 바꿔봤습니다.class UserRepositoryCustomImpl( private val queryFactory: JPAQueryFactory ) : UserRepositoryCustom { override fun findAllWithHistories(): List<User> { return queryFactory .select(user) .distinct() .from(user) .leftJoin(user.userLoanHistories, userLoanHistory).fetchJoin() .fetch() } }이렇게 바꾸고 쿼리를 찍히는 것을 확인하니까한 번에 fetch join 되면서 가져오는 것 같습니다! 한 번 확인해주시면 감사하겠습니다!
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
Class나 Entity 만들 때 접근제어자 관련해서 질문이 있습니다!
자바에서는 Entity나 클래스를 만들 때 접근 제어자로 private을 붙이는게 일반적이었는데요. 코틀린에서는 그렇게 하면 객체를 생성하고도 밖에서 바로 접근이 안 되는 거 같네요ㅠprivate을 붙여주고 custom getter 같은걸로 객체 생성 후 호출하게 해주는 것이 좋은가요? 아니면 접근 제어자를 안 붙이고 그냥 쓰는게 좋은가요..?
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
선생님 19강 UI 테스트 하시는 부분에서 질문이 있습니다.
19강 9분30초 지점에서 책 등록할 때는 400에러가 나면서 책 등록이 안 되는데 왜 그 전에 유저는 바로 정상적으로 등록이 되는걸까요?build.gradle에 implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.13.3' 이 디펜던시를 추가해주기 전에도 유저 등록은 정상적으로 되는 이유가 궁금합니다!제가 자바로 개발을 할 때도 웹 계층 DTO에 필드가 한 개만 있을 때는 잭슨이 정상적으로 작동 안 해서 @NoArgConstructor 어노테이션이나 @Setter 등을 꼭 붙여줘야 이게 정상 작동했던 경험이 있습니다. (구글링을 해보니 잭슨 라이브러리 쪽 이슈인데 아직도 open 상태라는 글을 본 거 같기도 합니다..)혹시 UserCreateRequest에는 프로퍼티가 2개 있고, BookRequest에는 프로퍼티가 1개 뿐이라 이런 일이 생긴 것인지도 좀 궁금하네요..
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
app 실행 시 종료된 프로세스 에러가 발생합니다.
어떻게 해결할 수 있을까요?
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
안녕하세요! @Nullable 관련해서 질문이 있습니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.이번 강의에서 플랫폼 타입으로 인해 Java 와 Kotlin 간에 발생할 수 있는 문제점을 설명해주셨는데요.특히, 아래의 코드를 테스트할 때 null 때문에 발생할 수 있는 문제점과 해결할 수 있는 방법을 설명해주셨습니다.assertThat(results[0].age).isNull()Java 클래스의 getter에 @Nullable을 붙여줌으로써 해결할 수 있었는데요.제가 궁금한 것은 롬복의 @Getter가 클래스 레벨에서 적용된 경우에는 어떻게 @Nullable을 붙여줄 수 있느냐가 궁금했습니다.코틀린으로 변환 과정에서 롬복의 @Getter가 만들어주는 게터들을 모두 하드 코딩으로 작성하고 나서 @Nullable 어노테이션을 해당하는 게터에 달아줘야하는건지, 아니면 더 좋은 방법이 있는지 궁금합니다!모든 클래스가 그렇지는 않겠지만 아무래도 기존에 사용하고 있던 자바 클래스 코드들에 @Getter 어노테이션이 달려 있을 것이라고 예상이 되고 이 경우에는 어떻게 테스트 해당 문제를 해결해야하는지 궁금하네요더불어 좋은 강의 감사합니다!
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
안녕하세요 강사님 도메인 생성 시 주 생성자에 관한 질문드립니다.
안녕하세요 강사님~ 강의 너무 재밌게 잘 보고 있습니다.강의중에 User 리팩토링 과정에서 userLoanHistories를 주생성자에 선언하셨는데@Entity class User( @Column(nullable = false) var name: String, val age: Int?, @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long? = null, ) { // 클래스 바디로 내려도 되나요? @OneToMany(mappedBy = "user", cascade = [CascadeType.ALL], orphanRemoval = true) val userLoanHistories: MutableList<UserLoanHistory> = mutableListOf() (...) }기존 자바코드에서는 이 컬랙션은 내부적으로 사용될뿐 getter로 접근하는 부분이 없기에 굳이 주생성자에 선언하는 것보다 클래스 바디로 내리는게 뭔가 더 자연스럽지 않나 하여 질문드렸습니다..!
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
.
.
- 해결됨실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
재활용 극대화를 위한 상속구조 + Mixin(!?) 구성에 대한 질문입니다.
한 3일동안 산넘고 물건너 아직 끝이 어딘지도 모르고 해매고 있습니다 ㅎㅎ 안녕하세요 강사님.상황:제목에서도 알 수 있듯, Kotlin Jpa Mixin 을 소개하는 글로 부터 힌트를 얻고, 소스코드:BitBucket 자료를 참고삼아 강의 16강 정도의 예제를 업그레이드 하고 강의를 계속 이어가려다, 돌부리에 걸려 자빠져 입원한듯, 강의를 이어갈수 없게 지체되어서 몇일째 끙끙 앓고있답니다. 제가 참고한 자료 자체가 너무 오래된 5년전 자료라, 최신자료를 찾아봐도 찾아지지 않아서 이 예제를 참고했는데, 이것조차 유효한 자료인지 가늠이 안되었지만 이걸 변형해서라도 조립형태로 가야겠다는 목표가 생겨서 이 가이드를 응용하기로 했습니다..Kotlin 에서 지원하는 Mixin 기법(맞는지 모르겠습니다)을 도전하게 되었어요. 엔티티, 테이블 모두 생성은 되는데, Mixin 속성은 적용이 안되어서, 테이블을 보면 덩그러니 ID 만 보입니다. 원인과 관련 자료가 너무 없어서 관둬야 하나... 하다가 핼프요청 하게 되었어요.제가 16강 예제와 와 위에 Mixin 예제로 재구성한 제 Gist(entities.kt) 를 보시면 아시겠지만 구조를 보여드리면 이렇습니다.entities.kt다이어그램:아래는..조립의 끝단에 있는 @Entity AuditableTestEntity 코드입니다./* Implementation */ @Entity class AuditableTestEntity constructor( name: String, age: Int?, ) : Identifier<Long>(), AccessTimeAuditable by AccessTimeAudit(), AccessorAuditable by AccessorAudit(), Nameable by Named(name), Ageable by Aged(age) 코드를 보면 위의 부품(인터페이스 by 구현체)들이 조립된 형태로 되어있습니다. 컴파일에도 문제가 없어 잘 되는가 싶었지만, [컴파일> 서버 기동] 이후 결과는 다음과 같습니다.DB 테이블 상황ID를 제외한 나머지(name, age, created..., 등) 속성이 전혀 반영이 안되었지요. 아래는 서버 구동시 테이블 생성 쿼리 로그입니다.Hibernate: create table auditable_test_entity ( id bigint generated by default as identity, primary key (id) )질문:@MappedSuperclass 를 @Entity 를 제외한 모든 클래스에 붙여도 보고, 필드용 에노테이션 역시 Interface 로 옮겨도 보고, Use-site (@get, @filed 등)를 붙여옮봐도, 인식이 안되는건 여전하더라구요. 그래서 혹시 이방식이 동작하지 않는 원인이라던지, Kotlin 설정이나 플러긴 버전의 차이 같은 누락 요인이라던지, 더 나은 방식이 있다면 조언을 얻고자 질문하게 되었습니다. 읽어주셔서 감사합니다.
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
코틀린 JPA 질문이 있습니다
안녕하세요.Sto라는 부모 엔티티가 있습니다.자식으로는 Realestate 라는 엔티티가 있습니다.해당 엔티티의 관계는 Sto + Realestate 이렇게 1개의 쌍을 이루어 생성이 됩니다.저는 @OneToOne 양뱡향 관계를 사용하고 있습니다.cascade 속성을 이용하여, Sto를 save 했을 때 하위 엔티티까지 함께 저장하려고 하고 있습니다.이때, 모든 엔티티를 val를 사용하려고 했는데 Sto 생성자 호출 시 하위 엔티티에서 Sto 엔티티의 값을 알 수가 없어서 생성이 불가한 상태입니다.물리적으로 Sto + Realestate는 한쌍인데 방법이 없을까 싶어 문의드립니다.var + null을 사용하면, 어떻게든 할 수 있을 것 같은데 양방향 설정을 위해 이렇게 풀어서 사용해야 하나 궁금하네요..@Entity @Table(name = "sto") class Sto( @Id @Column(name = "sto_id", nullable = false) private val id: String, @OneToOne( mappedBy = "sto", cascade = [CascadeType.PERSIST] ) val realestate: Realestate, @OneToOne( mappedBy = "sto", cascade = [CascadeType.PERSIST] ) val youtube: Youtube, ) @Entity class Realestate( @Id @Column(name = "realestate_id", nullable = false) private val id: String, @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "sto_id", nullable = false) val sto: Sto, ) fun main() { Sto( id = "sto_id", realestate = Realestate( id = "realestate_id", sto = 여기가 문제네요.. ) ) }
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
안녕하세요 강사님
개인적으로 공부를 하던 중 잘 풀리지 않아 문의드리게 되었습니다.java.kt다름이 아니라 실행시점에 샘플 데이터를 미리 저장시켜두고 싶어서 자바로 작성했던 위의 코드를 아래와 같이 코틀린으로 변경 후에 실행을 시켜보았습니다.그런데 실행을 시키면CGLIB, subclass 등 오류가 발생해서 구글 검색을 통해 최대한 해결해보려 하였으나, allOpen 설정도 해보고 이것저것 해보았음에도 해결하지 못해서 이렇게 염치불구하고 문의드리게 되었습니다 ㅜ 혹시 어떤 문제인지 아실까요??
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
build.gradle 파일 설정 질문
그래이들 설정 파일에 코틀린 라이브러리를 추가하는과정에 있어서 질의응답의 답글에 있는 레퍼런스를 참고하는 과정에 있어 특정 문단을 이해하기가 어려워 질문드립니다. 다음 레퍼런스를 참고 하였으며https://docs.spring.io/spring-boot/docs/3.1.1/reference/pdf/spring-boot-reference.pdf 7.11.1. Requirements 해당 세션에 있는 내용입니다.Since Kotlin classes are final by default, you are likely to want to configure kotlin-spring plugin inorder to automatically open Spring-annotated classes so that they can be proxied. 해당 부분입니다. 추가적으로 레퍼런스에서는 org.jetbrains.kotlin:kotlin-stdlib 및 org.jetbranins.kotlin:kotlin-reflect 가 클래스 패스에 존재햐아 한다는데, stdlib만 설정하신 이유도 궁금합니다.
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
assertThat import 문제
안녕하세요 강의를 진행하던 도중 assertThat의 import가이런 식으로 hamcrest의 import만 존재하는 이유가 무엇일까요?수동으로 import를 작성하면 문제없이 진행은 되고 있습니다.인터넷에 찾아보니 testImplementation 'org.assertj:assertj-core:3.20.2'을 추가하라는데 이미 spring-boot-start-test에 포함되어있어 문제는 없어보입니다.인텔리제이의 오류일까요?감사합니다!
- 해결됨실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
빌드 도구를 Gradle이 아닌 IntelliJ로 했을 때의 인식 오류(해결)
안녕하세요.강의 코드를 작성하던 도중 QUser 클래스가 UserRepositoryCustomImpl에서 인식이 되지 않는 오류가 발생하였습니다. 빌드도 다시 해보고, build 파일을 삭제하고 다시 빌드 해보고, 캐시도 삭제해봤는데도 인식이 안되길래, 혹시나 해서 설정에서 '다음을 사용하여 빌드 및 실행' 부분을 Gradle로 바꾸어주니 바로 인식이 되더라구요. 혹시나 저와 같은 상황에서 삽질하고 계신 분들을 위해 글 남깁니다 ㅎㅎ자세히 다시 읽어보니 일부 플러그인을 사용 시에 제대로 빌드가 되지 않을 수 있다고 적혀있네요..
- 해결됨실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
예외 처리 리팩토링 질문
안녕하세요.강의 들으며 재밌고 공부하고 있습니다. 감사합니다.예외 처리를 util패지키에 모아서 처리하는 것은 이해했습니다. 약간 궁금증 생겨서 문의 남겨봅니다!BookService의 코드 일부분 입니다. 여기서 보면 UserRepository와 BookRepository의 findByName에서 모두 fail()로 예외 처리를 하는데요, 이걸 그냥 리포지토리 계층의 메서드 자체에서 예외를 처리해주면 더 깔끔하지 않을까 하는 궁금증이 생겼습니다. 제가 지금까지 공부하면서는 리포지토리 계층에서 디폴트 메서드를 통해서 처리하는 코드도 봤고, 서비스 계층에서 처리하는 코드도 봐서 어떤 방식을 선호하시는지, 권장 하시는지 궁금합니다! 좋은 강의 감사합니다!
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
갑자기 test시 Build Failed이 발생합니다
안녕하세요.15강까지 강의를 듣고서 강사님처럼 마지막에 전체 테스트를 돌렸더니다음과 같이 빌드가 실패합니다 제가 뭘 잘못한걸까요? ㅜ
- 해결됨실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
assertThat import 문제
assertThat import 안되는 문제선생님 안녕하세요. 이번에 새로 수강하고 있는 수강생입니다.프로젝트 다운 받고 실행을 시켜려고 하는데 실행이 안돼서 따로 설정해서 돌리고 있습니다.Junit5까지는 진행했지만 assertThat 코드를 호출하는 진도에서 실행이 안되고 있습니다.혹시 어떤 방법으로 해결 할 수 있을까요? 찾아도 안나오네요 ㅠㅜbuild.gradle.kts 파일입니다import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("org.springframework.boot") version "3.0.6" id("io.spring.dependency-management") version "1.1.0" id("java") id("org.jetbrains.kotlin.plugin.jpa") version "1.7.22" // id("org.jetbrains.kotlin.plugin.spring") version "1.7.22" id("org.jetbrains.kotlin.kapt") version "1.7.22" kotlin("jvm") version "1.7.22" kotlin("plugin.spring") version "1.7.22" } group = "com.example.kotlin" version = "0.0.1-SNAPSHOT" java.sourceCompatibility = JavaVersion.VERSION_17 configurations { compileOnly { extendsFrom(configurations.annotationProcessor.get()) } } repositories { mavenCentral() } dependencies { implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation("org.jetbrains.kotlin:kotlin-reflect:1.7.22") implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.3") implementation("org.junit.jupiter:junit-jupiter:5.8.1") implementation("com.querydsl:querydsl-jpa:5.0.0") kapt("com.querydsl:querydsl-apt:5.0.0:jpa") kapt("org.springframework.boot:spring-boot-configuration-processor") runtimeOnly("com.h2database:h2") testImplementation("org.assertj:assertj-core:3.21.0") implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-web-services") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("org.jetbrains.kotlin:kotlin-reflect") developmentOnly("org.springframework.boot:spring-boot-devtools") annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation(kotlin("test")) } tasks { test { useJUnitPlatform() } withType<KotlinCompile> { kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "17" } } withType<Test> { useJUnitPlatform() } }
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
강사님 안녕하십니까 코틀린 var 선언에 대해서 질문이 있습니다.
var 를 선언하게 되면 setter 를 사용한 것 처럼 외부에서도 클래스 내부 필드에 접근하게 되어 캡슐화가 되지 않아서 setter 를 막아주고 싶습니다. 만약 그렇게 하고싶다면 모든 필드에 private set 을 선언해야할 것 같은데 중복코드의 느낌도 있고, 코틀린의 간결함이랑 멀어진다는 생각이 들었습니다. 보통 실무에서는 도메인, jpa 엔티티를 분리하는 방법이 아닌 set 을 막으려면 어떻게 처리를 하는지 궁금합니다.
- 해결됨실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
DTO의 개수가 많아질 경우에는 어떻게 관리하는게 좋을까요?
안녕하세요 강사님. 별도로 코프링 프로젝트를 진행하던 도중 궁금한 점이 생겨서 질문드립니다!프로젝트를 진행하다 보면 API가 늘어날수록 DTO의 개수도 어마어마하게 많아지는 경우가 많은데, 이 경우 코틀린에서는 어떻게 DTO를 관리하는게 좋을지 고민입니다.코틀린은 자바와 달리 public 클래스를 파일과 1:1로 대응시킬 필요가 없다보니 하나의 파일 마다 각 엔티티별로 연관된 DTO를 모아놓는 사례도 보이더라구요.이런 경우에 기존에는 자바를 쓸때처럼 패키지로 나눠서 DTO를 관리하고 있었는데 1번 그림처럼 하나의 파일에 연관된 DTO를 모아서 관리하는 것과 2번 그림처럼 패키지로 나눠서 DTO를 관리하는 것 중에 어느게 더 좋은 방법일까요?
- 해결됨실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
Service와 Dto
강의를 보던 중에 궁금한 점이 있어서 질문 남겨요!결론부터 말씀드리자면 Service 레이어에서 dto를 사용해도 되는지, dto는 어떤 계층까지 사용해도 되는지에 대해 궁금합니다!저는 보통 사용할 때 UI <-> Controller 사이에서 데이터를 교환하기 위해 dto를 사용하고, Service 에서는 비즈니스 로직 수행 후 엔티티를 반환하는? 그런 식으로 진행해왔는데 강의에서 보면 Sevice에서도 dto를 바로 반환해서 사용하더라구요..dto라는게 data transfer object라는 의미를 가지고 있으니 굳이 UI와 Controller 관계가 아니여도 계층과 계층간의 데이터를 이동할 때 dto를 만들어서 사용해도 되는 건가요?? 감사합니다!!
- 미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
Enum 관련하여 질문 드립니다.
Book Model에서 type을 String으로 지정해 주었는데, Test Code에서 isEqualTo("COMPUTER") 라고 하면 테스트가 실패합니다.출력을 보니 String이 아닌 듯 한데, 그럼 어떤 타입인 것인지 궁금합니다!Spring에서는 Enum으로만 다루고, DB에만 String으로 저장되는 것인가요?좋은 강의 감사드립니다 !