안녕하세요. 상속과 별로 연관된 질문은 아닌 듯 하지만 강의에서 나온 부분에 궁금증이 생겨 질문 남깁니다. val swimAbility: Int get() = 3 이라는 예제 코드를 작성하셨는데요. 코틀린은 어차피 필드를 선언하면 게터, 세터를 만들어주고 필드 선언 시 디폴트 값도 지정해줄 수 있는데 그렇다면 위와 같은 형태의 커스텀 게터는 굳이 구현할 필요 없는 것 아닌가? 하는 생각이 듭니다. 그냥 초기값 3을 갖는 필드를 선언하기만 하면 게터까지 알아서 만들어질 테니까요. 그냥 인터페이스의 게터 상속 의도를 표현하기 위해 별 의미나 실 용례는 없는 코드를 작성하신 거라고 봐도 될지? 아니면 저런 방식의 커스텀 게터에 제가 이해하지 못하는 어떤 의미가 있는 것일지가 궁금합니다. 감사합니다. ㅇ
자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
@PutMapping("/user") public void updateUser(@RequestBody UserUpdateRequest request){ String readSql = "select * from user where id=?"; String sql = "update user set name=? where id=?"; jdbcTemplate.update(sql, request.getName(), request.getId()); } 웹페이지에서 update를 발생시켜서 put 요청이 올라 왔을때 UserUpdateRequest dto에 id와 name이 들어 간다는건 웹에서 요청이 올라왔을때 json에 이미 해당 name에 대한 id 정보가 있다는 거죠? id는 db에서 자동적으로 생성해 준다고 했었는데, 이 id를 웹에서는 어떻게 알고 있나요?
1. 현재 학습 진도 몇 챕터/몇 강을 수강 중이신가요? 4-8강 2. 어려움을 겪는 부분 어느 부분에서 막히셨나요? chapter4/_2_event_with_participant 폴더의 EventJoinService 객체의 메서드 코드에 대한 질문입니다. 코드의 어떤 로직이 이해가 안 되시나요? @Transactional public void joinEvent(Long eventId, Long memberId) { Event event = eventRepository.findById(eventId) .orElseThrow(() -> new EntityNotFoundException("이벤트를 찾을 수 없습니다.")); Member member = memberRepository.findById(memberId) .orElseThrow(() -> new EntityNotFoundException("회원을 찾을 수 없습니다.")); // save()를 호출하지 않아도 Dirty Checking에 의해 Update 쿼리가 나가지 않나요? event.increaseParticipants(); eventRepository.save(event); EventParticipant participant = EventParticipant.builder() .event(event) .member(member) .build(); participantRepository.save(participant); } } 코드 블럭의 주석 란에 질문을 적어놓았습니다. 저 상황에서 save() 를 호출하는 이유가 궁금합니다. JPA 엔티티의 상태 변경분에 대한 쿼리는 트랜잭션 커밋 후, 자동으로 나가는 것으로 알고 있습니다. 혹시, 제가 잘못 알고 있는건지 궁금합니다.
안녕하세요 토비님!! 강의를 완강하고 제 프로젝트를 리팩토링하면서 피드백받고싶은점이 생겨 질문글을 올립니다. Repository Port를 기술에 종속시키지 않기 위해 Adapter에서 JPA, MyBatis, QueryDSL을 조합하는 구조를 선택했는데, 이 설계 방향이 적절한지 조언을 구하고 싶습니다. 현재 구조 core/ └── domain/ └── application/ └── required/ ← Port 인터페이스 └── ~Repository adapter/ └── persistence/ ├── ~RepositoryAdapter ← Port 구현체 ├── ~JpaRepository ← Spring Data JPA └── ~MybatisMapper ← Mybatis 매퍼 인터페이스 의존 관계 [Service] → [Repository] ←impl― [RepositoryAdapter] → [JpaRepository] → [MybatisMapper] → [JPAQueryFactory] (core) (core) (adapter) (adapter) 예시 @Repository @RequiredArgsConstructor public class ItemRepositoryAdapter implements ItemRepository { private final ItemJpaRepository itemJpaRepository; private final ItemMybatisMapper itemMybatisMapper; @Override public List<Item> findBySearchRequest(ItemSearchRequest request) { return itemMybatisMapper.findBySearchRequest(request) .stream() .map(Item::from) .toList(); } @Override public List<Item> saveAll(List<Item> items) { return itemJpaRepository.saveAll(items); } } @Repository @RequiredArgsConstructor public class AuctionRepositoryAdapter implements AuctionRepository { private final JPAQueryFactory jpaQueryFactory; private final AuctionJpaRepository auctionJpaRepository; @Override public void deleteAllByRegionAndRealmId(RegionType region, Long realmId) { QAuction qAuction = QAuction.auction; BooleanBuilder filter = new BooleanBuilder(); filter.and(qAuction.region.eq(region)); if (realmId == null) { filter.and(qAuction.realmId.isNull()); } else { filter.and(qAuction.realmId.eq(realmId)); } jpaQueryFactory.delete(qAuction) .where(filter) .execute(); } @Override public int saveAll(List<Auction> auctions) { if (auctions.isEmpty()) return 0; return auctionJpaRepository.saveAll(auctions).size(); } } 이 구조를 선택한 이유 동적 쿼리, 벌크 연산 등 JPA만으로 해결하기 어려운 케이스가 있어 MyBatis와 QueryDSL을 병행 사용하고 있습니다. 일반적인 방식인 Port 인터페이스가 Spring Data JPA Repository를 상속하는 구조를 채택하지 않은 이유: MyBatis나 QueryDSL 기반 구현체를 만들 수 없음 CustomRepository 인터페이스를 별도로 만들어야 하는 복잡도 증가 현재 방식의 장점: Port 인터페이스가 순수 Java 인터페이스로 유지됨 RepositoryAdapter에서 상황에 맞는 기술을 자유롭게 조합 가능 추가 인터페이스 없이 단순한 구조 유지 저는 현재 구조가 의존 관계도 외부에서 내부로 향하고 테스트도 쉬워서 괜찮다고 생각하는데 토비님의 생각도 듣고싶습니다!! 좋은 강의 감사합니다!!
package hellojpa; import javax.persistence.Entity; import javax.persistence.Id; @Entity public class Member { @Id private Long id; private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } package hellojpa; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; public class JpaMain { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); Member member = new Member(); member.setId(1L); member.setName("HelloA"); em.persist(member); tx.commit(); em.close(); emf.close(); } } C:\Users\User\.jdks\temurin-21.0.9\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2025.2.2\lib\idea_rt.jar=65054" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\study\ex1-hello-jpa\ex1-hello-jpa\target\classes;C:\Users\User\.m2\repository\javax\xml\bind\jaxb-api\2.3.0\jaxb-api-2.3.0.jar;C:\Users\User\.m2\repository\org\hibernate\hibernate-entitymanager\ 5.3.10.Final \ hibernate-entitymanager-5.3.10.Final .jar;C:\Users\User\.m2\repository\org\jboss\logging\jboss-logging\ 3.3.2.Final \ jboss-logging-3.3.2.Final .jar;C:\Users\User\.m2\repository\org\hibernate\hibernate-core\ 5.3.10.Final \ hibernate-core-5.3.10.Final .jar;C:\Users\User\.m2\repository\org\javassist\javassist\3.23.2-GA\javassist-3.23.2-GA.jar;C:\Users\User\.m2\repository\antlr\antlr\2.7.7\antlr-2.7.7.jar;C:\Users\User\.m2\repository\org\jboss\jandex\ 2.0.5.Final \ jandex-2.0.5.Final .jar;C:\Users\User\.m2\repository\com\fasterxml\classmate\1.3.4\classmate-1.3.4.jar;C:\Users\User\.m2\repository\javax\activation\javax.activation-api\1.2.0\javax.activation-api-1.2.0.jar;C:\Users\User\.m2\repository\org\dom4j\dom4j\2.1.1\dom4j-2.1.1.jar;C:\Users\User\.m2\repository\org\hibernate\common\hibernate-commons-annotations\ 5.0.4.Final \ hibernate-commons-annotations-5.0.4.Final .jar;C:\Users\User\.m2\repository\javax\persistence\javax.persistence-api\2.2\javax.persistence-api-2.2.jar;C:\Users\User\.m2\repository\net\bytebuddy\byte-buddy\1.9.5\byte-buddy-1.9.5.jar;C:\Users\User\.m2\repository\org\jboss\spec\javax\transaction\jboss-transaction-api_1.2_spec\ 1.1.1.Final \jboss-transaction-api_1.2_ spec-1.1.1.Final .jar;C:\Users\User\.m2\repository\com\h2database\h2\1.4.199\h2-1.4.199.jar hellojpa.JpaMain 1월 13, 2026 3:42:37 오후 org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation INFO: HHH000204: Processing PersistenceUnitInfo [ name: hello ...] 1월 13, 2026 3:42:37 오후 org.hibernate.Version logVersion INFO: HHH000412: Hibernate Core { 5.3.10.Final } 1월 13, 2026 3:42:37 오후 org.hibernate.cfg.Environment <clinit> INFO: HHH000206: hibernate.properties not found 1월 13, 2026 3:42:37 오후 org.hibernate.annotations.common.reflection.java .JavaReflectionManager <clinit> INFO: HCANN000001: Hibernate Commons Annotations { 5.0.4.Final } 1월 13, 2026 3:42:38 오후 org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator initiateService WARN: HHH000181: No appropriate connection provider encountered, assuming application will be supplying connections 1월 13, 2026 3:42:38 오후 org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator initiateService WARN: HHH000342: Could not obtain connection to query metadata : The application must supply JDBC connections 1월 13, 2026 3:42:38 오후 org.hibernate.dialect.Dialect <init> INFO: HHH000400: Using dialect: org.hibernate.dialect.H2Dialect 1월 13, 2026 3:42:38 오후 org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl makeLobCreatorBuilder INFO: HHH000422: Disabling contextual LOB creation as connection was null Exception in thread "main" java.lang.UnsupportedOperationException: The application must supply JDBC connections at org.hibernate.engine.jdbc.connections.internal.UserSuppliedConnectionProviderImpl.getConnection(UserSuppliedConnectionProviderImpl.java:44) at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:35) at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:106) at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:136) at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getConnectionForTransactionManagement(LogicalConnectionManagedImpl.java:254) at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.begin(LogicalConnectionManagedImpl.java:262) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.begin(JdbcResourceLocalTransactionCoordinatorImpl.java:236) at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:86) at hellojpa.JpaMain.main(JpaMain.java:16) Process finished with exit code 1 이거 에러 발생한 이유가 뭘까요? 강의 러닝타임은 11분대입니다.
안녕하세요! 11. 그래프와 인접행렬 강의를 듣다가 질문이 생겨 글을 남깁니다. 가중치 방향 그래프에서 가중치가 0인 간선이 문제 특성상 의미가 있을 경우 가중치가 0인 간선을 자바로 표현하는 방법이 있을까요? 기존처럼 0으로 표현해 버리면 간선이 없는 경우와 구분하기 어려울 것 같아서요. 검색 해보니 그런 경우에는 double 타입 행렬을 선언하고 간선이 없을 때 Double.POSITIVE_INFINITY 를 쓰는 것 같긴 한데 맞는 방법일까요? 그런 기법이 코딩테스트 풀 때 사용되는지도 궁금합니다.
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] update하고 응답할 때 어차피 request dto에 응답할 파라메터 값이 담겨져있는데 해당 값을 response dto에 할당해서 응답하면 되지 않을까요? 즉 제가 구상한 코드는 다음과 같습니다. @Operation(summary = "회원 수정") @PutMapping("{id}") public UpdateMemberResponse updateMemberV1(@Validated @RequestBody MemberUpdateDTO memberUpdateDTO, BindingResult bindingResult, @PathVariable("id") Long id){ memberService.update(memberUpdateDTO, id); return new UpdateMemberResponse(id, memberUpdateDTO.getName(), memberUpdateDTO.getCity(), memberUpdateDTO.getStreet(), memberUpdateDTO.getZipcode()); } 굳이 컨트롤러단에서 memberService.findOne(id)를 select문을 날려서 호출해서 준영속상태의 Member 엔티티의 값을 response dto에 할당하는 이유가 있을까요?
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 클린도 해보고 다시 시도해보아도 test때문에 실패 한다네요.. 왜이럴까요..??
안녕하세요! 남노씨님 덕분에 강의 잘 들으며 학습중입니다. part5.청팀홍팀 풀이로 보여주신 것에서 질문이 있습니다. 문제의 Input 예시 이해가 잘 되지 않았습니다. 제가 혼자 생각했을 때는, 주어진 friends[][] 배열을 인접리스트로 만들어야한다고 생각했고, 서로는 쌍방이니 양방향 그래프. 양방향 값을 인접리스트에 넣어주어야 한다고 생각했습니다. 근데 input 예시를 보니, 예시1은 서로 양방향 없이 구성되어있고, 예시2는 인접리스트처럼 서로 양방향으로 구성되어있습니다. 이상황에서 인접리스트를 구성하려니 예시2로는 중복이 발생하더라구요. 1. 예시 1,2 기준이 달라보이는데 어떻게 해석해야 좋을까요? 2. 양방향 그래프=무방향 그래프 같다고 볼 수 있나요? 이 문제의 경우 어떤 그래프인지, 구현의 차이점이 있는지 궁금합니다. 3. 풀이에서는 인접리스트를 별도로 안만들고, 받은 배열 자체를 인접리스트인것처럼 바로 사용하였는데, 이전 풀이와 비교해서 왜 이렇게 사용하였는지 궁금합니다. (문제에서 캐치할 수 있는 차이점이 뭘지) 4. dfs/bfs에서 사용하는 자료구조(큐,재귀/스택)는 풀이에 사용하지 않으셨는데 문제 상 필요 없는건지, 이분그래프일 때 사용 안해도 되는지 궁금합니다. (일단 bfs 큐 사용한 구조 만들고 시작했는데 이렇게 접근하면 안되는걸까요?ㅠㅠ) 이해 도와주시면 감사하겠습니다 :)
========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 아니오 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 솔직히 강의에 관련된 질문과는 거리가 먼 내용이어서 질문을 해야 하나 말아야 하나 고민하다가 결국 질문하는 게 좋겠다고 생각되어 질문을 올립니다. 강의 중에 강사님께서 중간중간에 test관련 공부를 열심히 해야한다고 하셨는데 혹시 어떤 식으로 공부해야 하는지 그리고 강사님께서는 어떻게 하셨는지, 또 추천하시는 서적이 있다면 그 서적의 제목이 어떻게 되는지 알고 싶습니다.
학습 관련 질문을 최대한 상세히 남겨주세요! 고민 과정도 같이 나열해주셔도 좋습니다. 먼저 유사한 질문이 있었는지 검색해보세요. 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요! 20:15 경 작성해주신 findByPath 의 함수에서 article_id 의 경우 함께 조회할 필요가 없나요? 이전에 생성했던 unique index 구조를 생각해보면 article_id 와 path 2개로 복합 인덱스를 생성하였기 때문에 게시글마다 path 에 대한 unique 함을 보장하는 것이기 때문에 조회 시에 findByArticleIdAndPath 과 같은 식으로 해야 할 것 같은데, 제가 잘못 이해한 부분이 있는지 궁금합니다!
1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요?예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 질문 제목 그 자체이긴합니다 인텔리제이 무료버전이 없어지고 통합되엇는데 https://www.jetbrains.com/ko-kr/idea/download/?section=windows 해당 사이트에 나와있는걸 다운로드 하면될까요