todoPagingCP.tsx에서 Link로 페이지 동적으로 만들었는데 페이지 클릭때마다 const res = await fetch( `http://localhost:8080/api/todos/list?page=${page}` ); todo/list/page에 있는 이코드가 실행이 되는건가요?
강의 막바지에 쿼리 로그를 한눈에 볼 수 있게하기 위한 라이브러리를 추가하고 실행하시는데요. 저는 pdf 내용대로 implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0' 위 라이브러리를 추가하고 실행해보아도 쿼리 실행 로그가 보이지 않아요ㅠ
영상에서는 이제 junit5를 의존관계로 가져간다고 나와있고 build.gradle에 있는 exclude가 junit4버전에 대한걸 exclude한다고 하시는데요.. 그럼 강의가 junit5버전 쓰시는거 아닌가요? pdf는 강의 영상이 junit4 버전을 기준으로 하신다는데 이것 때문에 헷갈려요
위는 강의 pdf 파일에서 캡쳐한 build.gradle 설정 내용입니다. 아래는 제가 프로젝트 생성후 캡쳐한 build.gradle의 의존성 사진입니다. pdf 설명대로 JUnit4를 추가했습니다. 그런데 pdf 파일에 testImplementation(‘org.springframework.boot:spring-boot-starter-test’) { exclude group: ‘org.junit.vintage’, module: ‘junit-vintage-engine’ } 가 있던데 이것도 추가해줘야하는 부분인가요? 없으면 추후 강의를 진행하는데 문제가 될까요? 현재 pdf 파일에 있는 build.gradle 내용과 제가 방금 프로젝트 생성 후의 build.gradle 내용과 조금 다른 것 같아 질문드립니다
입문자를 위한 Spring Boot with Kotlin - 나만의 포트폴리오 사이트 만들기
안녕하세요, 윈도우 환경에서 작업중입니다. 다름이 아니라 Gradle을 IDEA로 변경하면 Build 시에 Error가 떠서 AI에게 물어보니 Gradle로 변경하라 하여 변경하니 되는데 이렇게 작업해도 상관 없는 부분일까요? 오류메세지: Kotlin: [Internal Error] java.lang.NoClassDefFoundError: org/jetbrains/kotlin/com/intellij/psi/PsiElement at org.jetbrains.kotlin.noarg.fir.KtErrorsNoArg.<clinit>(KtErrorsNoArg.kt:32) at org.jetbrains.kotlin.noarg.fir.FirNoArgExtensionRegistrar.configurePlugin(FirNoArgExtensionRegistrar.kt:15) at org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar.configuredExtensionFactories_delegate$lambda$0(FirExtensionRegistrar.kt:294) at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:86) at org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar.getConfiguredExtensionFactories(FirExtensionRegistrar.kt:291) at org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar.configure(FirExtensionRegistrar.kt:270) at org.jetbrains.kotlin.fir.session.FirAbstractSessionFactory.createSharedLibrarySession(FirAbstractSessionFactory.kt:107) at org.jetbrains.kotlin.fir.session.FirJvmSessionFactory.createSharedLibrarySession(FirJvmSessionFactory.kt:53) at org.jetbrains.kotlin.cli.pipeline.jvm.JvmFrontendPipelinePhase.prepareJvmSessions$lambda$0(JvmFrontendPipelinePhase.kt:326) at org.jetbrains.kotlin.cli.common.SessionConstructionUtils.prepareSessions(FirSessionConstructionUtils.kt:324) at org.jetbrains.kotlin.cli.pipeline.jvm.JvmFrontendPipelinePhase.prepareJvmSessions(JvmFrontendPipelinePhase.kt:322) at org.jetbrains.kotlin.cli.pipeline.jvm.JvmFrontendPipelinePhase.executePhase(JvmFrontendPipelinePhase.kt:137) at org.jetbrains.kotlin.cli.pipeline.jvm.JvmFrontendPipelinePhase.executePhase(JvmFrontendPipelinePhase.kt:47) at org.jetbrains.kotlin.cli.pipeline.PipelinePhase.phaseBody(PipelinePhase.kt:68) at org.jetbrains.kotlin.cli.pipeline.PipelinePhase.phaseBody(PipelinePhase.kt:58) at org.jetbrains.kotlin.config.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:102) at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:22) at org.jetbrains.kotlin.config.phaser.CompilerPhaseKt.invokeToplevel(CompilerPhase.kt:53) at org.jetbrains.kotlin.cli.pipeline.AbstractCliPipeline.runPhasedPipeline(AbstractCliPipeline.kt:109) at org.jetbrains.kotlin.cli.pipeline.AbstractCliPipeline.execute(AbstractCliPipeline.kt:68) at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecutePhased(K2JVMCompiler.kt:79) at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecutePhased(K2JVMCompiler.kt:45) at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:90) at org.jetbrains.kotlin.cli.common.CLICompiler.exec(CLICompiler.kt:352) at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1617) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:569) at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360) at java.rmi/sun.rmi.transport.Transport$ 1.run (Transport.java:200) at java.rmi/sun.rmi.transport.Transport$ 1.run (Transport.java:197) at java.base/ java.security .AccessController.doPrivileged(AccessController.java:712) at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196) at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587) at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828) at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705) at java.base/ java.security .AccessController.doPrivileged(AccessController.java:399) at java.rmi/sun.rmi.transport.tcp.TCPTransport$ ConnectionHandler.run (TCPTransport.java:704) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$ Worker.run (ThreadPoolExecutor.java:635) at java.base/ java.lang.Thread.run (Thread.java:840) Caused by: java.lang.ClassNotFoundException: org.jetbrains.kotlin.com .intellij.psi.PsiElement at java.base/ java.net .URLClassLoader.findClass(URLClassLoader.java:445) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:592) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525) ... 42 more
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (아니오) [질문 내용] 안녕하세요. 컬렉션 조회 최적화 부분에서 페이징 + 검색 조건 관련해서 궁금한 점이 있어서 질문드립니다. 질문) Order 리스트 페이징을 하고 싶은데@BatchSize는 안쓰고 5번처럼 QueryDto직접 쿼리 2번 + map O(0) 방식으로 처리하려고 합니다. 이 때 만약 검색 조건이 toMany 로 맺어진 테이블 (orderItem.quantity, orderItem.item.name 등) 에 있다면 toOne 방향 루트 join fetch 쿼리 할 때 이 조건을 함께 포함시켜면 되는걸까요 (join orderItem .. where .. 같이) 예를들어 item.name이 "tesla"인 item을 포함하고 있는 모든 order를 페이징 적용해서 보여주고 싶은 경우에 어떻게 하면 좋을지 궁금합니다.
강의 19분부터 설명하시는 내용이 트랜잭션 매니저에 커밋하는 것이 논리 커밋이라고 하시는데요, 실제 DB에 커밋하는 물리 커밋도 코드상에서 트랜잭션 매니저를 통해서 진행되는 것 아닌가요? 이건 어떻게 이해해야 할까요? 물리 트랜잭션이라는 것이 별개로 존재하는 것이 아니라 논리 트랜잭션이 모여진 개념이라 결국 트랜잭션 매니저에 하는 논리 커밋이라는 것이 사실 물리 커밋도 포함하는 개념이라고 이해하여야 하나요? 예를들어 외부 내부 트랜잭션이 있을 때 각각은 논리 트랜잭션이지만 하나의 물리 트랜잭션으로 묶이죠. 그리고 실제로 코드상에서 외부 트랜잭션에서 커밋을 하여야 물리 커밋이 진행되는데 이때 외부 트랜잭션을 별개로 보면 논리 커밋을 진행 한 것이기도 하지만 물리 커밋이 진행된 것처럼 트랜잭션 매니저가 하는 것은 논리 커밋이다 라는 개념도 논리 커밋을 하는 것은 외부 트랜잭션 일 경우 물리 커밋을 포함한다. 이렇게 이해하여야하나요?
log.info("내부 트랜잭션 커밋"); txManager.commit(inner); log.info("외부 트랜잭션 커밋"); txManager.commit(outer); 전체 커밋하는 상황에서 내부, 외부 모두 커밋이 되어야 실제 물리 커밋이 이루어진다고 앞서 개념을 설명하실 때도 그렇고 이번 강의에서도 설명하셨습니다. 그런데 내부 커밋을 진행하면 아무 일도 발생하지 않고 외부 트랜잭션에서 커밋을 진행해야 실제 물리 커밋이 되는데 그렇다면 이때 내부 커밋을 진행하지 않아도 되나요? 아니면 모두 커밋돼야 커밋된다는 원칙에 따라 내부 커밋도 필수적으로 진행하여야하고 외부 커밋도 진행하여야하는 것인가요? 제 생각에는 정말 내부 커밋이 필요하다면 호출이 반드시 필요하다라고 설명하셨을 것 같은데 내부 커밋을 해도 아무것도 안한다고 하시니 내부 커밋 코드를 호출에 의문점이 생깁니다. 실제 물리 커밋은 외부 커밋에서 진행되기 때문에 내부 커밋 코드를 강의 설명 차원에서 작성하신 것인지 아니면 정말 원칙에 따라 필요해서 호출한 것인지 궁금합니다.
spring-boot 버전 4.0.0 으로 프로젝트를 생성하면 어플리케이션 구동 시 아래와 같은 오류가 발생합니다. (현재 2025-12-08) 3.x 버전으로 내리면 발생하지 않으니 참고해주세요. 2025-12-08T18:40:05.881+09:00 INFO 2496 --- [splearn] [ main] .s.b.d.c.l.DockerComposeLifecycleManager : Using Docker Compose file /Users/coffeenjava/work/study/splearn/compose.yaml 2025-12-08T18:40:06.285+09:00 ERROR 2496 --- [splearn] [ main] o.s.boot.SpringApplication : Application run failed tools.jackson.core.exc.StreamReadException: Unexpected character ('\' (code 92)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false') at [Source: REDACTED StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION disabled); byte offset: #UNKNOWN] at tools.jackson.core.JsonParser._constructReadException(JsonParser.java:1800) ~[jackson-core-3.0.2.jar:3.0.2]
히카리 프록시 커넥션 객체를 커넥션을 반환할 때 생성해서 반환하는건가요? 4분 5초와 5분 30초 설명부터 커넥션을 반환할 때 히카리 프록시 커넥션 객체를 생성해서 커넥션을 내부에 감싸서 반환하는 것으로 이해됩니다. 이 객체가 조회할 때 생성되는 것이 아니라 반환할 때만 생성해서 반환해 주는 것인가요? 즉 커넥션을 조회할 때는 그냥 커넥션을 그대로 조회하고 반환할 때만 프록시 객체를 생성해서 감싸 반환하는 것인가요?
@PrePersist 가 있는 메서드는 영속성 컨텍스트에 엔티티를 저장할때 즉, save()나 persist() 호출 시점에 호출되는것인가요? 아니면 flush()이후에 INSERT쿼리가 실행되기 직전에 호출되는것인가요? @PreUpdate 가 있는 메서드는 엔티티의 변경 감지가 일어나고 트랜잭션 커밋 또는 em.flush()시점에 UPDATE쿼리가 실행되는데, 이 UPDATE쿼리가 실행되기 직전에 호출되는것이 맞을까요?
16강 '외부 연동을 다루는 방법'의 04:15에 보면, service.port 패키지로 이동한 UserRepository가 infrastructure에 있는 UserEntity에 의존하고 있는 상태입니다. 아마 후속 강의에서 UserEntity에 대한 의존도 해소될 것으로 예상되지만, 여기에서도 언급은 해주시면 더 좋을 것 같습니다.
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. h2.bat 을 실행하거나 cmd 들어가서 실행하면 실행까지는 되는데 콘솔이 안열립니다.
안녕하세요 토비님 강의 잘 수강하고 있습니다. 좋은 강의 감사드립니다. 저는 JPA엔티티를 도메인 모델로 사용하고 애플리케이션에서 이를 리턴하고 있습니다. 그런데 새로운 팀원 한명이 이렇게 이야기하더군요 이전에 마이바티스를 사용하다가 JPA가 나온거처럼 이를 대체하려면 코드변화가 필요할 것 입니다 사실 이것도 저는 맞는 말이라고 생각합니다. JPA 엔티티를 참조하는 모든 부분을 수정이 필요할 것 같습니다. 그럼에도 불구하고, 트레이드오프 관점에서 보면 현재 잘 사용하는 JPA엔티티를 그대로 사용하는게 더 효과적이라고 생각합니다. 여기서 궁금한게, 이렇게 새로운 데이터접근 기술이 나오게 되는 것까지 고려하는게 맞을까요? 어떠한 논리를 펼쳐서 JPA를 그대로 의존하는게 좋다고 이야기하는게 더 설득력이 있을까요?