묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
h2 데이터베이스 설치
윈도우11에서 h2 데이터베이스 설치해서 cmd에서 h2.bat를 실행했는데 아무창도 뜨지 않습니다. 관리자 권한으로 실행해도 똑같이 아무창도 뜨지 않는데 어떻게 해야 되나요???위와 같이 오류는 나지 않는데 아무창도 뜨지 않습니다.
-
미해결[개정판 2023-11-27] Spring Boot 3.x 를 이용한 RESTful Web Services 개발
Spring 3.xx 이상이라면 SpringDoc 사용하세요
Spring 3 이상부터는 더 이상 Springfox가 아닌 SpringDoc으로 해야 Swagger 설정을 해줄 수 있습니다.자세한 내용은 제가 참조한 아래 레퍼런스 확인해보시면 좋을 거 같아요 https://springdoc.org/https://colabear754.tistory.com/99https://velog.io/@kjgi73k/Springboot3%EC%97%90-Swagger3%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0 아래는 참고하여 작성한 코드입니다. @Configuration public class SwaggerConfig { @Bean public OpenAPI openAPI(){ return new OpenAPI() .components(new Components()) .info(apiInfo()); } private Info apiInfo() { return new Info() .title("Springdoc 테스트") .description("Springdoc을 사용한 Swagger UI 테스트") .version("1.0.0"); } } @RestController @RequestMapping("/swagger") public class SwaggerController { @Operation(summary = "문자열 반복", description = "파라미터로 받은 문자열을 2번 반복합니다.") @Parameter(name = "str", description = "2번 반복할 문자열") @GetMapping("/returnStr") public String returnStr(@RequestParam String str) { return str + "\n" + str; } @GetMapping("/example") public String example() { return "예시 API"; } @Hidden @GetMapping("/ignore") public String ignore() { return "무시되는 API"; } } NOTE:springdoc.swagger-ui.path에서 swagger url 기본 경로를 설정합니다. 저는 아래와 같이 /swagger로 접속하게끔 했습니다.# SPRINGDOC springdoc.packages-to-scan=com.example.dateanu.rest_api springdoc.default-consumes-media-type= application/json;charset=UTF-8 springdoc.default-produces-media-type= application/json;charset=UTF-8 springdoc.swagger-ui.path=/swagger springdoc.swagger-ui.disable-swagger-default-url=true springdoc.swagger-ui.display-request-duration=true springdoc.swagger-ui.operations-sorter=alpha
-
미해결스프링 시큐리티
인가 프로세스 DB 연동 웹 계층 구현 - 2) 관리자 시스템 - 권한 도메인, 서비스, 리포지토리 구성 질문
안녕하세요 강사님. 인가 프로세스 DB 연동 웹 계층 구현 섹션에서 "2) 관리자 시스템 - 권한 도메인, 서비스, 리포지토리 구성" 강의 수강 중 궁금한 점이 있어 질문 드립니다. Resources 테이블과 연관된 메뉴인 "리소스 관리"에서 순서 필드는 어떤 용도로 사용될까요?단순히 리소스 데이터를 조회할 때 order by 를 통한 정렬을 위한 필드인지, 다른 용도로도 사용되는지 궁금합니다.
-
해결됨자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
연관관계의 주인을 파악하는 방법에 대해 궁금한 점이 있습니다.
연관관계의 주인은 곧 외래키를 갖고 있는 테이블이 그 연관관계의 주인으로 이해가 됩니다.SQL문의 create table을 통해서 보면 외래키가 명확하게 드러나서 연관관계의 주인이 누구인지 파악이 비교적 수월한데, JPA의 코드를 통해 보면 누가 관계의 주인인지 잘 모르겠습니다.물론 그것을 파악하기 쉬우라고 mappedBy를 이용해서 주인이 아니라는 것을 표시한다는 것은 알겠는데, 만약 이것이 안적혀 있더라도, 코드만 보고 관계의 주인을 파악하는 방법이 있을까요?
-
해결됨자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
domain\user\User.java 파일에 updateName 메서드에 대한 궁금증이 있습니다.
package com.group.libraryapp.domain.user; import com.group.libraryapp.domain.user.loanhistory.UserLoanHistory; import javax.persistence.*; import java.util.ArrayList; import java.util.List; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id = null; @Column(nullable = false, length = 20, name = "name") private String name; private Integer age; // ManyToOne의 관계이기 때문에 List 사용 @OneToMany(mappedBy = "user") // mappedBy는 연관관계의 주인이 아닌 쪽에 붙는다. private List<UserLoanHistory> userLoanHistories = new ArrayList<>(); protected User() { } public User(String name, Integer age) { if (name == null || name.isBlank()) { throw new IllegalArgumentException(String.format("잘못된 name(%s)이 들어왔습니다.", name)); } this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Long getId() { return id; } public void updateName(String name) { this.name = name; } } 궁금증은 간단합니다. updateName과 setName의 차이점이 무엇인지 궁금합니다.updateName 또한 setName 처럼 User 객체의 name 프로퍼티를 변경해주기 위한 메서드로 보입니다.이름만 다를 뿐 형태가 똑같은데 굳이 updateName 이란 메서드를 만드는 이유가 궁금합니다.updateAPI에 맞춰서 통일성을 주기 위해 updateName 메서드를 만든 것인지, update의 요구 조건에 따라 updateName이 변경될 가능성이 있기 때문에 확장성 때문에 만든건지 아니면 어떠한 이점이 있는 것인지 등등 그 목적이 알고 싶습니다.
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
PostConstructor 관련해서 질문있습니다!
안녕하세요 항상 강의 잘 보고 있습니다.영한님께서 알려주신 내용으로 공부와 토이프로젝트를 병행해나가다 이해가 가질 않는 부분이 있어서 질문드립니다.상황A클래스에 @PostConstructor 어노테이션을 붙여 객체 a를 미리 저장해 DB에 저장을 하고 B클래스에도 @PostConstructor를 붙여 객체 b를 저장하려 하였습니다.(A클래스와 B클래스의 연관관계는 일대다입니다.) a객체에 b객체를 리스트 형태로 저장할 수 있게끔 빈 리스트를 만들어 저장하는 것까지 A클래스에서 확인을 하였고 B클래스에서 b객체를 만들고 아까 저장한 a객체를 DB에서 가져오는것까지 확인하였습니다.이후 a객체와 b객체의 연관관계를 연관관계 편의 메서드로 만들어주려하였으나 a객체에서 b객체들을 담을수 있게끔 만들어둔 리스트 형식의 필드가 lazyinitializationexception 예외를 발생시키며 더미데이터 생성에 실패하였습니다.시도해 본 것들@OneToMany의 기본 로딩 전략이 지연로딩이기에 생긴 문제인가 싶어 em.flush, @GraphEntity, hibernate.initialize까지 해보았으나 똑같이 lazyinitializationexception를 발생시키며 더미데이터 생성에 실패하였습니다.(혹시나 해서 즉시로딩으로 변경하니 더미데이터 생성은 문제없이 잘 되었습니다.)궁금한 점혹시 어떤 이유로 다음과 같은 현상이 발생했는지 알 수 있을까요?
-
미해결스프링 시큐리티
세션 클러스터링을 한 이후 동시로그인 제한이 안되는데요
안녕하십니까강사님 강의를 듣고 여기 커뮤니티에 나름 최신 소스 받아서 시큐리티 구현중인데요이중화 환경에서 톰캣을 통해 세션을 공유하는것까지는 되었는데요동시 로그인제한이 안되는데 추가적인 설정을 무엇을 해야할지 모르겠는데도움좀 받을수 있을까요? 스프링 2.7.10스프링 시큐리티 5.7.7 // 시큐리티 설정부분@Slf4j @RequiredArgsConstructor @EnableWebSecurity @Configuration public class WebSecurityConfig { private final MemberRepository memberRepository; @Bean public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { // 경로 설정 http. authorizeRequests() .antMatchers().permitAll() .anyRequest().authenticated() ; // 동시 로그인 제한을 설정 http .sessionManagement() .maximumSessions(1) .expiredUrl("/error/expired") .and().sessionCreationPolicy(SessionCreationPolicy.ALWAYS) ; http.logout() .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) .invalidateHttpSession(true) .clearAuthentication(true) .deleteCookies("JSESSIONID") ; // 로그인... 인증 권한 체크... // 로그인 return http.build(); } /** * 여기에 Authentication 을 설정하도록 */ @Bean AuthenticationManager authenticationManager(AuthenticationConfiguration authConfiguration) throws Exception { return authConfiguration.getAuthenticationManager(); } @Bean public static PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } // 톰캣 클러스터링 부분 (https://happy-jjang-a.tistory.com/155를 참조했습니다.)@Configuration public class TomcatClusterConfig implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> { @Override public void customize(final TomcatServletWebServerFactory factory) { factory.addContextCustomizers(new TomcatClusterContextCustomizer()); } } class TomcatClusterContextCustomizer implements TomcatContextCustomizer { @Override public void customize(final Context context) { context.setDistributable(true); DeltaManager manager = new DeltaManager(); manager.setExpireSessionsOnShutdown(false); manager.setNotifyListenersOnReplication(true); context.setManager(manager); configureCluster((Engine) context.getParent().getParent()); } private void configureCluster(Engine engine) { //cluster SimpleTcpCluster cluster = new SimpleTcpCluster(); cluster.setChannelSendOptions(6); //channel GroupChannel channel = new GroupChannel(); //membership setting McastService mcastService = new McastService(); mcastService.setAddress("228.0.0.4"); mcastService.setPort(45564); // TCP&UDP port 오픈 필요 mcastService.setFrequency(500); mcastService.setDropTime(3000); channel.setMembershipService(mcastService); //receiver NioReceiver receiver = new NioReceiver(); receiver.setAddress("auto"); receiver.setMaxThreads(6); receiver.setPort(5000); // TCP port 오픈 필요 channel.setChannelReceiver(receiver); //sender ReplicationTransmitter sender = new ReplicationTransmitter(); sender.setTransport(new PooledParallelSender()); channel.setChannelSender(sender); //interceptor channel.addInterceptor(new TcpPingInterceptor()); channel.addInterceptor(new TcpFailureDetector()); channel.addInterceptor(new MessageDispatchInterceptor()); cluster.addValve(new ReplicationValve()); cluster.addValve(new JvmRouteBinderValve()); cluster.setChannel(channel); cluster.addClusterListener(new ClusterSessionListener()); engine.setCluster(cluster); } }
-
미해결호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)
Count 쿼리 발생에 대해 궁금합니다.
안녕하세요 호돌맨님 ! 질문이 있습니다 !!Pageable 을 사용해서 페이징 구현 시 Full Scan 을 하기 위해 Count 쿼리가 발생하는걸 확인했는데, Pageable 에서는 페이징 처리를 위해 총 데이터의 개수를 파악해야 하기 때문이니까 Count 쿼리가 필요한거고 Querydsl 은 직접 limit 값, offset 값을 지정하기 때문에 Full Scan 할 필요가 없으니 Count 쿼리가 필요없는게 맞을까요 ?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
create() 함수에서 input tag에서의 값을 MemberForm으로 받는 이유가 있나요?
@PostMapping("members/new") public String create(String name){ Member member = new Member(); member.setName(name); MemberService.join(member); return "redirect:/"; }위 코드처럼 String을 이용해 form에서 데이터를 받아오면 안 되는 건지 궁금합니다
-
미해결실습으로 배우는 선착순 이벤트 시스템
Kafka 처리량 조절 관련 문의드립니다
며칠전 수강시작했구요. 첫 완강한 인프런 유료강의가 되었네요.앞으로도 이러한 스타일 (주제중심, 적당한 총 길이)의 강의를 더 만들어주시면 감사하겠습니다.업무환경에서 다양한 기술스택을 경험하기 어려운 개발자들도 경험하면 좋을 기술스택도 좀 포함되면 더할나위 없이 좋을것 같구요. 제 경우엔 이 강의 덕분에 아주 오래전 살짝 경험해본 Redis 를 복습하게 되었고, Kafka 에 대해서도 입문하게 되었습니다.질문드립니다.이 강의에서 Kafka 이용의 장점은 처리량 조절이라고 말씀주셨습니다.처리량 조절의 구체적인 방안은구성방식, 요건등 상황에 따라 다양한 안이 있긴 하겠지만혹시 알려주실만한 방안이 있을까요? 개인적으로 찾아본것은 컨슈머 옵션중fetch.max.wait.ms 또는 fetch.max.bytes같은 옵션을 이용하면 괜찮겠다라는 생각이 들긴 했습니다.(쓰면서 생각드는건데.... 만약 두개 동시에 이용시 OR 조건으로 동작해야 될텐데.. 라는 생각이...) 경험하신 사례이든, 참고할만한 링크이든 혹시 알려주실수 있다면 감사하겠습니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
HomeController 클래스 통해서 home.html 렌더링되는 과정이 이게 맞는 건지 궁금해요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]1. 애플리케이션이 실행될 때, @Controller annotation이 있는 HomeController class의 instance가 스프링 컨테이너에 bean으로서 등록2. 사용자가 localhost:8080 입력하면 tomcat 서버가 받고, 스프링 컨테이너에 @GetMapping("/")이 있는 bean 탐색3. HomeController class 내부에 있는 home()이 @GetMapping("/")이 있고, 문자열 "home"을 return하므로 templates 폴더에 있는 home.html 렌더링됨, 컨테이너에서 이미 대응되는 bean을 찾았으므로 static 폴더에 있는 index.html는 렌더링 X이 과정이 맞을까요?
-
미해결실전! 스프링 데이터 JPA
long 반환타입
MemberJpaRepository의 count 함수에서 Long이 아닌 long 으로 반환타입을 작성 하는 이유가 뭔가요?Long으로 해도 상관 없는걸까요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
MemberServiceTest 똑같이 작성했는데 java: ';' expected 에러가 자꾸 떠요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. package hello.hellospring.service;import hello.hellospring.domain.Member;import hello.hellospring.repository.MemoryMemberRepository;import org.assertj.core.api.Assertions;import org.junit.jupiter.api.AfterEach;import org.junit.jupiter.api.BeforeAll;import org.junit.jupiter.api.BeforeEach;import org.junit.jupiter.api.Test;import static org.assertj.core.api.Assertions.*;import static org.junit.jupiter.api.Assertions.assertThrows;public class MemberServiceTest {MemberService memberService; MemoryMemberRepository memberRepository; @BeforeEach public void beforeEach() {memberRepository = new MemoryMemberRepository(); memberService = new MemberService(memberRepository); }@AfterEach public void afterEach() {memberRepository.clearStore(); //코드가 끝날때마다 clear @Test void 회원가입() {// given Member member = new Member(); member.setName("hello"); // when long saveId = memberService.join(member); // then Member findMember = memberService.findOne(saveId).get(); Assertions.assertThat(member.getName()).isEqualTo(findMember.getName()); }@Test public void 중복_회원_예외() {// given Member member1 = new Member(); member1.setName("spring"); Member member2 = new Member(); member2.setName("spring"); // when memberService.join(member1); //then IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2)); Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다."); }// //then// try{// memberService.join(member2);// fail();// }catch (IllegalStateException e){// // assertThat을 통해 두 객체가 같은지 확인한다.// Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.1232131");// } @Test void findMember() {}@Test void findOne() {}}
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
homebrew와 m1 맥북으로 설치했다면 아래 명령어로 경로 확인 가능
mysql 접속 후 아래 명령어 2가지를 통해 알 수 있음.show variables like 'datadir';select @@datadir;
-
미해결스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
Service 단 Test Code 작성 요령
안녕하세요~ 예전에 TC 를 작성하면서 발생한 궁금점들이 이번 강의를 통해서 다시 한번 생기게 되어서 질문 올리게 되었습니다!!UserSerivce 를 Test 하기 위해 UserRepository 모킹주입을 하였습니다. 이 때, stub 을 사용하여 모킹 객체의 동작을 정의해주는데, 제가 예전에 이렇게 했을 때 (강의 예제와 같은) UserRepository 의 동작을 일괄적으로 관리하기 위해 @BeforeEach 를 사용하였습니다. |이렇게 했더니 실제로 많은 일을 수행하는 Repository 에 들어가는 when 절이 정말 많아지고 BeforeEach 가 매우 길어져서(필요한 연관 객체들 User 와 연관된 A,B,C 등의 Entity 모두 그 때 그 때 생성해주는 코드까지 다 결합되어 있었음), 이게 과연 맞는가? 싶은 생각이 들었습니다. 해당 강의를 통해서 그냥 그렇게 하는게 맞았었나보네 싶은데 , 보통 그렇게 BeforeEach 혹은 각 TC 코드가 길어져도 이렇게 Test 하는게 관례적인 모습일까요?그간 물어볼 사람이 없어서 못 물어봤는데 이렇게 질문드릴 수 있게 되어서 다행입니다 ㅠ
-
미해결예제로 배우는 스프링부트 입문
33강 jpa 질문입니다
33강 하고 있는데요..디비 설정부분에서 에러가 납니다.데이터소스 설정이 안되어있다고 하는거 같은데...몇 번을 뒤져봤는데도 제 눈에는 안 보네요..ㅠFailed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.Reason: Failed to determine a suitable driver classAction:Consider the following: If you want an embedded database (H2, HSQL or Derby), please put it on the classpath. If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).build,gradle의 디펜던시입니다dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' testImplementation 'org.springframework.boot:spring-boot-starter-test' runtimeOnly 'com.oracle.database.jdbc:ojdbc8' }의존성은 dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' testImplementation 'org.springframework.boot:spring-boot-starter-test' runtimeOnly 'com.oracle.database.jdbc:ojdbc8' }persistence 설정은 아래와 같습니다..<properties> <property name="jakarta.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver" /> <property name="jakarta.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:xe" /> <property name="jakarta.persistence.jdbc.user" value="scott" /> <property name="jakarta.persistence.jdbc.password" value="tiger" /> <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle12cDialect" />
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
서버 실행
이리저리 해봐도 에러는 없는거 같은데 서버 실행이 안되네요... 어떻게 해결할수 있을까요??
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
램이 16기가인데 문제 없이 강의의 사비스들을 실행시킬 수 있나요?
램이 16기가인데 강의에 나오는 서비스들을 문제없이 실행시킬 수 있나요??
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
@BatchSize와 SQL Parsing
안녕하세요. 강의 잘 듣고 있습니다.BatchSize라는 기능을 배워서 상당히 놀라웠는데요.해당 기능을 사용해 실행되는 쿼리를 보니IN (?, ?)와 같이 바인딩 변수를 이용하는 것으로 보이는데만약 말씀하신것처럼 BatchSize를 1000개로 잡았다 할 떄최악의 경우 IN절 내부의 ? 바인딩 변수가 계속 변하게 된다면 (1개 ~ 1000개 )소프트 파싱의 이점을 살리지 못하는 경우가 발생할 수도 있나요 ??항상 좋은 강의 만들어주셔서 감사합니다
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
spring initializr 문의드립니다
현재날짜기준,gradle-groovygradle-kotlinmaven 3개뿐입니다. 영상처럼 gradle-java 가 없어요ㅠ