inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

173만명의 커뮤니티!! 함께 토론해봐요.

@Configuration과 @Transactional

미해결

스프링 DB 2편 - 데이터 접근 활용 기술

안녕하세요 항상 강의를 잘 보고 있습니다. @Configuration과 @Transactional 둘 다 상속을 이용한 proxy기법(CGLIB, AOP)을 사용하는 것으로 확인하였습니다. 만약 저가 MemberService라는 class에 @Service, @Transactional를 부여한 후 ComponentScan을 하면 MemberService의 프록시 객체가 빈으로써 생성되어 스프링 컨테이너에 반환되는 것을 확인하였는데 궁금한 것은 @Configuration과 @Transactional 이 둘이 각각 프록시를 생성하는 것인지 혹은 하나만 생성하는 것인지가 궁금합니다. 두 번째로 궁금한 것은 프록시는 싱글톤으로 관리가 될 텐데, 프록시가 아닌 target이 가르키는 실제 객체 MemberService는 매 request마다 객체가 새로 생성되어지는 것인지 혹은 최초로 서버가 로드할 때 한 번만 생성이 되는 것인지 궁금합니다. (제 생각에는 @Configuration으로 인하여 후자이지 않을까 생각합니다.)

  • spring
  • mvc
  • jpa
  • querydsl
  • spring-data-mybatis
  • spring-jpa
우기바나 댓글 1 좋아요 0 조회수 78

한탄스럽네여

미해결

스프링 DB 2편 - 데이터 접근 활용 기술

분명 다 똑같이 따라왔는데 JdbcTemplate - 이름 지정 파라미터3 에서 코드를 돌렸더니 작동을 안하네요... 이전강좌까지 다 잘됐는데 아..............................................혹시나해서 완성코드 받아서 복붙해도 작동 안하네요 Ai답변이 딴소리 해주겠지만 오류때문에 미칠 노릇이네요 풀이자꾸 꺾입니다...

  • spring
  • mvc
  • jpa
  • querydsl
  • spring-data-mybatis
  • spring-jpa
berichmore 댓글 2 좋아요 0 조회수 199

html 소스코드 질문

미해결

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 소스코드는 도대체 어디서 가지고 오시는거일까요???

  • spring
  • mvc
김현우 댓글 1 좋아요 0 조회수 185

JPA 프록시 객체 AccessType.FIELD에서 getId 시 초기화?

해결됨

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 안녕하십니까 선생님! 질문 제목을 보고 얘는 왜 이 질문을 여기에 올렸을까라고 의아해하실 수도 있는데, 사실 제가 영한님 스프링 관련 강의는 다 사서 열심히 보고 있는데(정말 도움 많이 받고 있습니다. 항상 정말 잘 듣고 있습니다!!) JPA는 영한님이 쓰신 JPA 책을 사서 보고 있습니다! 그런데 프록시 객체 파트를 읽어보던 도중 이해가 되지 않는 부분이 있어 질문을 쓰고 싶은데 JPA 쪽에 질문으로 쓰려고 해도 강의를 산 사람만 작성할 수 있어 부득이하게 여기에서 질문하게 되었습니다 죄송합니다 ㅜㅜㅜ 다름이 아니라 지금 JPA의 프록시 객체 파트를 공부하고 있습니다. 그런데 294P 의 8.1.2 프록시와 식별자 부분에서 엔티티를 em.getReference, 즉 프록시로 조회할 때 엔티티 접근 방식을 AccessType.PROPERTY 로 설정한 경우 getId를 호출해도 프록시를 초기화하지 않는다고 하셨습니다. 그래서 직접 한번 코드를 작성해보았습니다. 우선 AccessType.PROPERTY 방식부터 적용해보았습니다. PROPERTY와 FIELD 두 방식 모두 실험 전 create 옵션으로 Parent 객체 하나를 만들어두고 후에 none으로 바꾸어 진행했습니다. Parent 객체 생성 코드 Parent parent = new Parent(); parent.setId(1L); parent.setName("parent1"); em.persist(parent); Parent.java @Entity @Setter @Getter @Access(AccessType.PROPERTY) public class Parent { private Long id; private String name; @Id public Long getId() { return id; } } JpaMain.java public static void main(String[] args) { EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); Parent foundParent = em.getReference(Parent.class, 1L); System.out.println(foundParent.getClass()); System.out.println(foundParent.getId()); System.out.println(foundParent.getName()); tx.commit(); em.close(); emf.close(); } 해당 코드를 실행시켰을 때 이렇게 나온걸 보니 확실히 getId 후에 getName 조회시 프록시 객체를 초기화(select 구문 실행)을 했다는 것을 알 수 있었습니다. 그런데 AccessType.FIELD로 조회하면 getId 를 할때에도 프록시 객체를 초기화한다고 하여 아래와 같이 Parent.java의 코드를 다시 작성하여 JpaMain.java를 실행해보았습니다. Parent.java @Entity @Setter @Getter @Access(AccessType.FIELD) public class Parent { @Id private Long id; private String name; } 제 예상으로는 getId 실행시 프록시 객체를 초기화 한다고 하셨으니 실제 출력에는 Parent의 getId()가 실행되기 전에 select 문이 실행되어야 할 것이라고 예상하였습니다. 하지만 위와 같이 getId()에는 프록시 객체를 초기화하지 않는 것처럼 보여지는 출력이 나왔습니다. 책에서는 AccessType.FIELD 사용시 getId()를 호출하면 JPA는 getId()가 id만 조회하는 메소드인지 다른 필드까지 활용해서 어떤 일을 하는 메소드인지 알지 못하므로 프록시 객체를 초기화한다 고 나와있는데 왜 이런 결과가 나온 것일까요? 제가 잘못 이해하고 있는 것이 있을까요?

  • java
  • spring
  • mvc
  • spring-boot
  • jpa
도등어 댓글 2 좋아요 0 조회수 174

onclick이 쿼리 파라미터 전송을 하는건가요?

미해결

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 상품 수정 버튼을 클릭했을 때 이동하는 경로를 Thymeleaf 템플릿 엔진을 써서 작성했는데 <button class="w-100 btn btn-primary btn-lg" onclick="location.href='editForm.html'" th:onclick="|location.href='@{/basic/items/{itemId}(itemId=${item.id})/edit}'|" type="button">상품 수정</button> 이런 경우에 실제 주소 뜨는걸 보면 http://localhost:8080/basic/items/%7BitemId%7D(itemId=$%7Bitem.id%7D)/edit 이렇게 뜨고 만약 다음과 같이 작성하면 <button class="w-100 btn btn-primary btn-lg" onclick="location.href='editForm.html'" th:onclick="|location.href='@{/basic/items/{itemId}/edit(itemId=${item.id})}'|" type="button">상품 수정</button> http://localhost:8080/basic/items/2/edit 이렇게 경로가 뜨는데 왜 이런 차이가 발생하는 건가요? 제가 처음 이렇게 한 이유가 (itemId=${item.id}) 이게 치환되는 주체는 {itemId}여야 하는 거고 그러면 선언 위치는 사실 상관없는 거 아닌가 해서 저렇게 했는데 실제 url을 까보니까 아예 다르게 나와서 왜 이렇게 되는건지 궁금합니다. 그리고 또 하나의 궁금증으로는 강사님께서 수정 부분 컨트롤러 메서드를 작성하실 때 다음과 같이 작성하셨는데 public String editForm(@PathVariable Long itemId, Model model) 그러면 위 코드를 보았을 때 아까 보았던 코드를 기반으로 생각했을 때 th:onclick="|location.href='@{/basic/items/{itemId}/edit(itemId=${item.id})}'|" ItemId 가 쿼리 파라미터 형식으로 전송되면서 서버로 넘어가는 지 그것도 궁금합니다.

  • spring
  • mvc
sim2 댓글 1 좋아요 0 조회수 110

members.jsp white 오류가 뜹니다.

미해결

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

스프링 의존성 추가하고 properties도 추가했는데 오류가 납니다. 다른분들이 고치신대로 WEB-INF도 만들어봤는데 안되네요 ㅜㅜ 오류는 이렇게 납니다... ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요.

  • spring
  • mvc
상준 댓글 2 좋아요 0 조회수 242

Rollback-only 설정 위치

미해결

스프링 DB 2편 - 데이터 접근 활용 기술

평소 열심히 강의를 듣고 있는 일반적인 대학생입니다. 트랜잭션 동기화 매니저에 대해 의문사항이 많아 직접 찾아보다가 강의와 다른점이 있어 질문드립니다. 아직 부족한 학생인만큼 어느정도의 뇌피셜은 들어있습니다.. (물론 코드에 기반한) 질문은 가독성을 위해 음슴체를 사용한점 양해부탁드립니다.. 결론 트랜잭션 rollback-only 은 트랜잭션 status에 있으며 해당 사실 확인은 TransactionManager에 의해 밝혀진다. 따라서, rollback-only 표시가 동기화 매니저에 있다는 설명은 수정이 필요한 것 같습니다.. -> 트랜잭션 동기화 매니저는 관련이 없는 것 아닌가 라는 생각이 듭니다.. 그 이유는 아래와 같습니다. 강의제공 내용 내부 롤백이 일어나면 Rollback-only 표시가 됨 외부 커밋은 해당 표시를 보고 true라면 롤백 해당 표시는 트랜잭션 동기화 매니저에 있음 (08:18 쯤) 고민하다가 의문이 든 내용 트랜잭션 동기화 매니저는 쓰레드(요청)마다 적절한 트랜잭션을 찾아 주는 역할이라고 생각함 -> 트랜잭션의 상태를 관리하도록 하진 않을 것 같다는 생각이 듦 (뇌피셜) 트랜잭션 매니저를 보다보니 getTransaction 을 호출하면 Status를 반환함 -> 가만 생각해보면 트랜잭션 commit rollback을 트랜잭션 매니저가 하는데 상태관리도 트랜잭션 매니저가 하는게 맞지 않을까? (rollback-only 표시도 트랜잭션 매니저가 하는게 맞지 않을까?)라는 생각을 하게됨 코드를 까보니 실제로 해당 메서드로 추정되는 메서드가 있음 실제 코드 JpaTransactionManger protected void doSetRollbackOnly(DefaultTransactionStatus status) { JpaTransactionObject txObject = (JpaTransactionObject)status.getTransaction(); if (status.isDebug()) { this.logger.debug("Setting JPA transaction on EntityManager [" + txObject.getEntityManagerHolder().getEntityManager() + "] rollback-only"); } txObject.setRollbackOnly(); } 위의 코드는 내부적으로 사용하는 코드인 것 같음 (뇌피셜, 이 코드가 동작하는 것이 아닌가) 또한 아래와 같은 메서드도 존재함 public void setRollbackOnly() { EntityTransaction tx = this.getEntityManagerHolder().getEntityManager().getTransaction(); if (tx.isActive()) { tx.setRollbackOnly(); } if (this.hasConnectionHolder()) { this.getConnectionHolder().setRollbackOnly(); } } public boolean isRollbackOnly() { EntityTransaction tx = this.getEntityManagerHolder().getEntityManager().getTransaction(); return tx.getRollbackOnly(); } 아마 전자가 실제로 TransactionManager가 활용하는 코드인 것 같음 (protected라서), 후자는 외부에서 임의로 rollback-only를 설정할 때 사용하는 메서드인 것 같음 (EntityTransaction은 더 들어가보니 hibernate에서 트랜잭션을 관리하는 클래스인 것 같음) DataSourceTransactionManager 해당 매니저에도 비슷한 메서드가 존재함 public void setRollbackOnly() { getConnectionHolder().setRollbackOnly(); } @Override public boolean isRollbackOnly() { return getConnectionHolder().isRollbackOnly(); } 런타임 디버깅을 돌려보며 정확히 어떤 메서드가 동작하는 지 확인해봄. 아마도 aop로 프록시 객체가 사용되는 것 같은데 aop 부분은 아직 학습하지 않아서 모르겠음.. AbstractPlatformTransactionManager -> datasourceTransactionManger의 doSetRollbackOnly 호출 위와 같은 코드를 보았을 때, rollback-only와 같은 트랜잭션의 상태는 트랜잭션 매니저에 의해 관리 되는 것 같고 트랜잭션 동기화 매니저는 관련이 없는 것 아닌가라는 생각이 듭니다..

  • spring
  • mvc
  • jpa
  • querydsl
  • spring-data-mybatis
  • spring-jpa
김채윤 댓글 2 좋아요 0 조회수 186

build.gradle에 추가했는데 안됩니다....

미해결

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

build.gradle에 추가했고 properties에 추가했는데 안됩니다....! ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요.

  • spring
  • mvc
상준 댓글 2 좋아요 0 조회수 324

JSP Dependence 문제

미해결

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

build.gradle랑 다 추가하고 업데이트해서 적용되게 했는데 오류가 나는데 어떻게 해야되나요? ㅜ ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요.

  • spring
  • mvc
댓글 1 좋아요 0 조회수 201

파일 실행이 안됩니다.

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] HomeController.java 와 home.html을 다 작성하고 localhost:8080으로 실행하려고 하니 HomeController.java가 실행이 안됩니다. 인터넷에는 src를 리소스 루트로 지정하고 하면 된다고 해서 리소스 루트로 src를 지정하고 첫 번째 사진과 같이 파일 위치를 지정하는 부분에서 계속 없다고 뜨는데 어떻게 해야하나요?

  • java
  • spring
  • mvc
  • spring-boot
simjiyoung12 댓글 2 좋아요 0 조회수 176

인터셉터 무한루프

미해결

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 안녕하세요 해당 강의처럼 인터셉터 두개를 사용하여 요청을 했더니 인터셉터가 계속 호출되는 오류가 발생하였습니다. 오류의 원인은 LoginCheckInterceptor의 exclude pattern에 /login 경로를 추가하지 않아 발생한 것이었습니다. 교안과 비교하며 주먹구구식으로 해결하였지만 능동적으로 해결하기 위해서는 어떤 과정을 거쳐야 하나요? 처음에는 두 인터셉터에 브레이크포인트를 찍어 디버깅 하려 했지만 여러 복잡한 코드들을 마주하게 되더라구요.. 어떻게 이런 오류를 해결해야 하나요?

  • spring
  • mvc
ililil 댓글 1 좋아요 0 조회수 133

13분에 createQuery를 할려고 하는데 . qlString이 안 뜹니다 !

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

학습하는 분들 께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요.

  • java
  • spring
  • mvc
문정욱 댓글 2 좋아요 0 조회수 142

콘솔창에 warn이 안떠요

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 콘솔창에 warn이 뜨지 않습니다. 스프링을 먼저 실행한 후에 http://localhost:8080/hello-mvc 에 들어가서 오류가 나와도 콘솔창에 warn이 나오지 않습니다. 어떻게 해야할까요?

  • java
  • spring
  • mvc
  • spring-boot
댓글 1 좋아요 0 조회수 132

junit Test에서 오류는 나지 않지만 결과가 다르게 나오네요

미해결

스프링 프레임워크는 내 손에 [스프2탄]

안녕하세요 초기 egov에서 받을 때 최신인 5.3.6버전을 받아서 그런지 초기 DataSourceTest에서 @RunWith는 jUnit4버전을 가리키고 저는 5.3.6버전의 spring을 이용했어서인지 SpringJunit4ClassRunner.class가 import 되지 않아 난항을 겪던 중 pom.xml의 버전을 강사님처럼 5.0.7 RELEASE 버전으로 수정하면서 chat gpt의 도움을 받아 DataSourceTest의 테스트를 실행할 수 있었습니다. 그러나 console에서 연결이 되었다는 메세지도 없으며 이를 이상하게 여기고 root-context.xml에 기입된 비밀번호를 강사님처럼 일부러 틀리게 한 후 실패를 기대한 상태로 run을 돌렸지만, jUnit에 Failures가 뜨지도 않습니다.. 혹시 이런 경우에도 방법이 있을까 하여 코드도 함께 첨부합니다.. (pom.xml은 다른 글에 올려주신 참고 블로그의 것을 인용했습니다.) [pom.xml] => 10000자를 올릴 수 없다하며 노션 링크를 첨부하겠습니다! https://devfighting.notion.site/18410212999180b5b0a9cd4ada3a6a58?pvs=4 [console결과, jUnit 결과] [maven dependencies]

  • spring
  • jquery
  • mvc
  • jpa
  • spring-security
taetae 댓글 2 좋아요 0 조회수 240

로그아웃 구현시 memberId 값을 어떻게 가져오는건지 궁금합니다.

미해결

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] @PostMapping("/logout") public String logout(HttpServletResponse response){ expireCookie(response, "memberId"); return "redirect:/"; } 로그아웃 구현시 expireCookie메소드를 생성 후 두번째 인자로 들어가는 memberId를 어떻게 가져오는건지 궁금합니다. logout메소드 생성시 인자로 추가한것도 아닌데 .. 스프링컨테이너가 클라이언트에서 요청시 쿠키정보에 memberId라는 쿠키이름이 있으면 가져오게 되어있는건가요?

  • spring
  • mvc
댓글 1 좋아요 0 조회수 125

Assertions에서 org.assertj.core.api가 안보입니다ㅜㅜㅜ

미해결

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

테스트 코드 작성중 Assertions에 org.assertj.core.api가 안보입니다 어떻게 해야되나요? ㅜ ㅜ ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요.

  • spring
  • mvc
상준 댓글 1 좋아요 0 조회수 108

gradle 빌드 오류

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

Execution failed for task ':test'. 라고만 계속뜨네요 인텔리제이도 다시 설치해봤는데...혹시 이메일을 알려주신다면 제가 project 파일을 보내드려도될까요?

  • java
  • spring
  • mvc
  • spring-boot
전우영 댓글 2 좋아요 0 조회수 246

@Transactional을 붙여도 Rollback이 되지 않는 문제는 해결했으나 이유륾 모름

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 해결했습니다. 복붙하는 과정에서 private Connection getConnection() { return DataSourceUtils.getConnection(dataSource); } 이 부분이 있는 걸 몰랐네요 저는 conn = dataSource.getConnection() 으로 진행해서 문제가 생긴거였습니다 그런데 추가적인 질문으로 이렇게 했을 때는 롤백이 되지 않는 이유가 무엇인가요? 강의 코드와 똑같이 수정했음에도 롤백되지 않고 계속 DB에 반영이 됩니다. 참고로 다른 질문글의 conn 관련된 수정도 이미 했음에도 롤백되지 않습니다. JdbcMemberRepository package hello.hello_spring.Repository; import hello.hello_spring.Domain.Member; import org.springframework.jdbc.datasource.DataSourceUtils; import javax.sql.DataSource; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.Optional; public class JdbcMemberRepository implements MemberRepository { // DB와 연동하려면 Datasource가 필요함 private final DataSource dataSource; public JdbcMemberRepository(DataSource dataSource) { this.dataSource = dataSource; } @Override public Member save(Member member) { String sql = "insert into member(name) values(?)"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = dataSource.getConnection(); pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); pstmt.setString(1, member.getName()); pstmt.executeUpdate(); rs = pstmt.getGeneratedKeys(); if (rs.next()) { member.setId(rs.getLong(1)); } else { throw new SQLException("id 조회 실패"); } return member; } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public Optional<Member> findById(Long id) { String sql = "select * from member where id = ?"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = dataSource.getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setLong(1, id); rs = pstmt.executeQuery(); if (rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); return Optional.of(member); } else { return Optional.empty(); } } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public List<Member> findAll() { String sql = "select * from member"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = dataSource.getConnection(); pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); List<Member> members = new ArrayList<>(); while (rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); members.add(member); } return members; } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public Optional<Member> findByName(String name) { String sql = "select * from member where name = ?"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = dataSource.getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setString(1, name); rs = pstmt.executeQuery(); if(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); return Optional.of(member); } return Optional.empty(); } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } private void close(Connection conn, PreparedStatement pstmt, ResultSet rs) { try { if (rs != null) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (pstmt != null) { pstmt.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (conn != null) { close(conn); } } catch (SQLException e) { e.printStackTrace(); } } private void close(Connection conn) throws SQLException { DataSourceUtils.releaseConnection(conn, dataSource); } } SpringConfig package hello.hello_spring; import hello.hello_spring.Repository.JdbcMemberRepository; import hello.hello_spring.Repository.MemberRepository; import hello.hello_spring.Repository.MemoryMemberRepository; import hello.hello_spring.Service.MemberService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; @Configuration public class SpringConfig { private DataSource dataSource; @Autowired public SpringConfig(DataSource dataSource) { this.dataSource = dataSource; } @Bean public MemberService memberService() { return new MemberService(memberRepository()); } @Bean public MemberRepository memberRepository() { return new JdbcMemberRepository(dataSource); } } MemberServiceIntegrationTest package hello.hello_spring.Service; import hello.hello_spring.Domain.Member; import hello.hello_spring.Repository.MemberRepository; import hello.hello_spring.Repository.MemoryMemberRepository; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; // 테스트는 반복해서 시도할 수 있어야 하기 때문에 DB에 데이터를 인서트 쿼리하고 '롤백' 해주는 것 (정확히는 DB에 반영을 안하는 것) // 이를 위해서 @Transactional 사용 @SpringBootTest @Transactional class MemberServiceIntegrationTest { // 테스트는 특수한 용도이기 때문에 일회성(?)으로 필드 주입을 해도 무관 @Autowired MemberService memberService; @Autowired MemberRepository memberRepository; @Test void 회원가입() { // given Member member = new Member(); member.setName("spring"); // when Long saveId = memberService.join(member); // then Member one = memberService.findOne(saveId).get(); assertThat(member.getName()).isEqualTo(one.getName()); } @Test public void 중복_회원_예외() { // given Member member1 = new Member(); member1.setName("spring"); Member member2 = new Member(); member2.setName("spring"); // when memberService.join(member1); IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> memberService.join(member2)); assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다."); // try { // memberService.join(member2); // } catch (IllegalArgumentException e) { // assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다."); // } // then } }

  • java
  • spring
  • mvc
  • spring-boot
Dongni 댓글 1 좋아요 0 조회수 133

Transactional 질문 있씁니다.

미해결

스프링 DB 1편 - 데이터 접근 핵심 원리

[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 현재 재직중인 직장 소스를 보면 트랜잭션을 걸어야하는 서비스단 메서드에 @Transactional의 격리 수준이 READ UNCOMMITTED 로 모두 되어있습니다. 하나도 빠짐없이.. 상사분의 말로는 테이블 락 발생을 방지하기 위해 이렇게 한다는데... 영한님의 의견이 궁금합니다. 제가 생각했을때 이는 적합하지 않은 방법같거든요. 정합성이 깨질뿐더러 테이블 락은 다른 방법으로 해결해야지 이건 아닌것 같더라구요.. 답변 기다리겠습니다!

  • spring
  • mvc
  • spring-jdbc
backendman 댓글 1 좋아요 0 조회수 152

try-with-resources 구문 사용 관련 질문드립니다.

해결됨

스프링 DB 1편 - 데이터 접근 핵심 원리

[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 해당 강의에서는 save(Member member)를 작성하면서 try-catch구문을 썼는데 아래처럼 try-with-resources구문을 사용하면 생길 수 있는 문제가 있어서 try-catch구문을 쓰는건가요? try (Connection con = getConnection(); PreparedStatement pstmt = con.prepareStatement(sql)) { pstmt.setString(1, member.getMemberId()); pstmt.setInt(2, member.getMoney()); pstmt.executeUpdate(); return member; } catch (SQLException e) { log.error("db error", e); throw e; } 제가 혼자 생각해봤었을 때의 이때의 생길 수 있는 문제점은 try(...)안의 자원들의 close()가 호출될 때가 아닌 생성될 때의 오류가 생기면 그걸 catch로 잡거나 그러지 못할수도 있다는 것이었습니다. 실제로 h2데이터베이스를 끄고 실행해봤었을 때, Connection con = getConnection(); 부분에서 예외가 발생했고, catch로 잡지 못하는 모습이었습니다. 이처럼 자원 생성에서부터 예외가 발생할 때 try-with-resources를 사용하는 것은 적절치 않다고 생각하면 되는걸까요?

  • spring
  • mvc
  • spring-jdbc
문예찬 댓글 2 좋아요 0 조회수 191

인기 태그

인프런 TOP Writers

주간 인기글