월 66,000원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨스프링과 JPA 기반 웹 애플리케이션 개발
의존성 설정 관련 질문있습니다.
안녕하세요~ 강의 너무 잘 보고 있습니다. 프로젝트 생성부터 전부 따라서 해보고 있는데요. pom.xml 파일에 의존성 설정을 선생님과 똑같이 했는데 @Valid와 @Length 애노테이션 관련 의존성이 추가가 안되었더라구요. 메이븐 리포지토리에서 검색해서 아래와 같이 의존성을 따로 추가해서 해결하긴 했는데요. <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.4.10.Final</version> </dependency> pom.xml 파일에서 스프링 부트 2.3.0 버전을 사용했다는 차이만 있는데 이렇게 의존성 차이가 있는 이유가 궁금합니다~
- 해결됨스프링과 JPA 기반 웹 애플리케이션 개발
로그인과 로그인 유지에서
안녕하세요! 로그인과 로그인 유지에 대해 질문이 있습니다!! 강의에서는 이메일과 닉네임으로 모두 로그인이 가능하게 되어있는데 로그인을 할 때 이메일로만 로그인이 가능하도록 하면서 로그인을 했을 때 타임리프에서 #authentication.name으로 닉네임을 가져올 수 있는 방법이 있을까요?? 아래와 같이 UserAccount에서 username 자리에 account.getNickname()를 넣어주어야 #authentication.name 에 닉네임이 들어갈텐데.. @Getter public class UserAccount extends User { private Account account; public UserAccount(Account account) { super(account.getNickname(), account.getPassword(), List.of(new SimpleGrantedAuthority("ROLE_USER"))); this.account = account; } } 이메일로만 로그인이 가능하도록 하려면 loadUserByUsername 메서드에서 이메일로 찾지 못한 경우 닉네임으로 유저를 찾도록 하는 코드를 지워야 하고, 그렇게 되면 RememberMe 를 통한 로그인 유지에서 jsessionid를 지운 경우 Remember-me 쿠키에 담긴 username이 닉네임이므로 loadUserByUsername 메서드에서 account를 찾을 수 없게 됩니다. @Transactional(readOnly = true) @Override public UserDetails loadUserByUsername(String emailOrNickname) throws UsernameNotFoundException { Account account = accountRepository.findByEmail(emailOrNickname); if(account == null){ account = accountRepository.findByNickname(emailOrNickname); } if(account == null){ throw new UsernameNotFoundException(emailOrNickname); } return new UserAccount(account); } 이러한 경우 어떻게 해야 User클래스의 username에 닉네임을 넣었을 때, 이메일로만 로그인이 가능하도록 하면서 로그인 유지 기능을 정상적으로 동작시킬 수 있을지 궁금합니다..!!
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
EntityGraphType설정에 관해
안녕하세요. 언제나 좋은 강의 너무 감사드립니다. 다름이 아니라 본영상에 8:43초 쯤에 나오는 EntityGraphType이 FETCH 타입과 LOAD타입이 있는데요. @EntityGraph(value ="Study.withTagsAndManagers", type = EntityGraph.EntityGraphType.FETCH)Study findStudyWithTagsByPath(String path); 이것의 타입을 FETCH로 해서 태그를 더하는 액션을 취할경우, 다음과 같은 SQL이 발생합니다. 2020-05-17 09:34:12.745 DEBUG 8292 --- [io-8080-exec-10] org.hibernate.SQL : select study0_.id as id1_4_0_, tag2_.id as id1_9_1_, account4_.id as id1_0_2_, study0_.closed as closed2_4_0_, study0_.closed_date_time as closed_d3_4_0_, study0_.full_description as full_des4_4_0_, study0_.image as image5_4_0_, study0_.path as path6_4_0_, study0_.publish_date_time as publish_7_4_0_, study0_.published as publishe8_4_0_, study0_.recruit_update_date_time as recruit_9_4_0_, study0_.recruiting as recruit10_4_0_, study0_.short_description as short_d11_4_0_, study0_.title as title12_4_0_, study0_.use_banner as use_ban13_4_0_, tag2_.title as title2_9_1_, tags1_.study_id as study_id1_7_0__, tags1_.tags_id as tags_id2_7_0__, account4_.bio as bio2_0_2_, account4_.email as email3_0_2_, account4_.email_check_token as email_ch4_0_2_, account4_.email_check_token_generated_at as email_ch5_0_2_, account4_.email_verified as email_ve6_0_2_, account4_.joined_at as joined_a7_0_2_, account4_.location as location8_0_2_, account4_.nickname as nickname9_0_2_, account4_.occupation as occupat10_0_2_, account4_.password as passwor11_0_2_, account4_.profile_image as profile12_0_2_, account4_.study_created_by_email as study_c13_0_2_, account4_.study_created_by_web as study_c14_0_2_, account4_.study_enrollment_result_by_email as study_e15_0_2_, account4_.study_enrollment_result_by_web as study_e16_0_2_, account4_.study_updated_by_email as study_u17_0_2_, account4_.study_updated_by_web as study_u18_0_2_, account4_.url as url19_0_2_, managers3_.study_id as study_id1_5_1__, managers3_.managers_id as managers2_5_1__ from study study0_ left outer join study_tags tags1_ on study0_.id=tags1_.study_id left outer join tag tag2_ on tags1_.tags_id=tag2_.id left outer join study_managers managers3_ on study0_.id=managers3_.study_id left outer join account account4_ on managers3_.managers_id=account4_.id where study0_.path=? 2020-05-17 09:34:12.745 TRACE 8292 --- [io-8080-exec-10] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [aaaa] 2020-05-17 09:34:12.748 DEBUG 8292 --- [io-8080-exec-10] org.hibernate.SQL : select tags0_.account_id as account_1_1_0_, tags0_.tags_id as tags_id2_1_0_, tag1_.id as id1_9_1_, tag1_.title as title2_9_1_ from account_tags tags0_ inner join tag tag1_ on tags0_.tags_id=tag1_.id where tags0_.account_id=? 2020-05-17 09:34:12.748 TRACE 8292 --- [io-8080-exec-10] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [86] 2020-05-17 09:34:12.749 DEBUG 8292 --- [io-8080-exec-10] org.hibernate.SQL : select tag0_.id as id1_9_, tag0_.title as title2_9_ from tag tag0_ where tag0_.title=? 2020-05-17 09:34:12.749 TRACE 8292 --- [io-8080-exec-10] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [aaaa] 2020-05-17 09:34:12.750 DEBUG 8292 --- [io-8080-exec-10] org.hibernate.SQL : delete from study_tags where study_id=? 2020-05-17 09:34:12.751 TRACE 8292 --- [io-8080-exec-10] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [87] 문제는 2번째 발생하는 SQL입니다. 제가 생각했을때는 tags와 managers에 관련된 SQL만 발생해야 하는데, 왜 중간에 account_tags 테이블로부터 태그 정보를 얻으려 하는지 모르겠습니다.이 테이블은 settingsController에서 태그 관련 액션시 이용되는 테이블이라고 생각하고 있습니다. 디버그해보니, @CurrentUser시점에서 불러들이는 account의 tags와 zones는 size=0임을 알수 있습니다. ...그렇다고 해도, getStudyToUPdateTag가 불러졌을때 account_tags가 불려지는 이유를 도무지 알수가 없습니다.EntityGraphType을 FETCH가 아닌 LOAD타입으로 바꾸면 account_tags관련 SQL이 나오지 않습니다. 제가 코딩을 잘못한 것일까요? 아니면 이 단계에서는 이렇게 나오는게 정상인가요? PS:백기선님의 github에서 master브랜치를 디버깅 -> account_tags관련 SQL 안나옴. -> 원인분석 실패...만일을 대비해, 제 깃헙 링크도 첨부합니다.https://github.com/yongsoo-kim/studyolle/tree/feature/ph4_study_feature/src/main/java/com/studyolle/studyolle/study
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
모든 종류의 어노테이션을 사용하는 이유가 따로 있을까요?
@Setter 뿐만 아니라 AllArgsConstructor 등 모든 종류의 생성자 및 세터를 선언하면 데이터 핸들링에 문제가 생기지 않나요?
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
@ManyToMany에 관련된 질문입니다.
안녕하세요. 백기선님의 강의를 실습해보면서 소모임이라는 웹 프로젝트를 따로 만들어 보는 중입니다. 강의에 해당하는 스터디 만들기를 실행했을 때 NullPointerException이 발생했고 제일 먼저 강의에서는 Study에 해당하는 엔티티인 Society엔티티의 addManager에서 에러가 발생했다는것은 알았는데 디버깅을 해보니 Society엔티티에서 managers에 new HashSet<>();으로 초기화를 했음에도 불구하고 null이 나왔습니다. 디버깅을 더 진행하였더니 TargetException으로 넘어갔는데 여기서부터 어떻게 해결해야 할지 모르겠습니다. 아래는 Society 엔티티이고 분명히 @ManyToMany의 연관관계를 맺은 부분에 new HashSet으로 초기화를 시켰는데 초기화되지 않고 null이 되는지 궁금합니다. package me.weekbelt.runningflex.modules.society;import lombok.*;import me.weekbelt.runningflex.modules.account.Account;import me.weekbelt.runningflex.modules.account.UserAccount;import me.weekbelt.runningflex.modules.tag.Tag;import me.weekbelt.runningflex.modules.zone.Zone;import javax.persistence.*;import java.net.URLEncoder;import java.nio.charset.StandardCharsets;import java.time.LocalDateTime;import java.util.HashSet;import java.util.Set;@Builder @AllArgsConstructor @NoArgsConstructor@Getter @EqualsAndHashCode(of = "id")@Entitypublic class Society { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToMany private Set<Account> managers = new HashSet<>(); @ManyToMany private Set<Account> members = new HashSet<>(); @Column(unique = true) private String path; private String title; private String shortDescription; @Lob @Basic(fetch = FetchType.EAGER) private String fullDescription; @Lob @Basic(fetch = FetchType.EAGER) private String image; @ManyToMany private Set<Tag> tags = new HashSet<>(); @ManyToMany private Set<Zone> zones = new HashSet<>(); private LocalDateTime publishedDateTime; private LocalDateTime closedDateTime; private LocalDateTime recruitingUpdatedDateTime; private boolean recruiting; private boolean published; private boolean closed; private boolean useBanner; public String getEncodedPath() { return URLEncoder.encode(this.path, StandardCharsets.UTF_8); } public void addManager(Account account) { this.managers.add(account); } public boolean isJoinable(UserAccount userAccount) { Account account = userAccount.getAccount(); return this.isPublished() && this.isRecruiting() && !this.members.contains(account) && !this.managers.contains(account); } public boolean isMember(UserAccount userAccount) { return this.members.contains(userAccount.getAccount()); } public boolean isManager(UserAccount userAccount) { return this.managers.contains(userAccount.getAccount()); }}
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
확인 메일 재전송 문의
현재 Email Check Token 의 생성과 생성시간을 도메인에서 같이 관리하는데 이 비즈니스 로직은 계정을 처음 생성할 때만 호출합니다. public void generateEmailCheckToken() { emailCheckToken = UUID.randomUUID().toString(); emailCheckTokenGeneratedAt = LocalDateTime.now(); } 현재 코드로는 회원 가입 후 한시간이 지난 후면 계속 메일을 보낼 수 있을 것 같습니다. (따라서, 제 생각에는 수정이 필요해 보입니다.) 질문은 여기서 부터입니다. 그럼에도 일단 도메인에서 이렇게 만드신 이유는 체크 메일을 보낼 때 마다 토큰을 새로 생성해서 갱신하시려는 의도셨을 까요? 그런 의도가 맞다면 혹은 위의 의도대로 하려면 send mail 할 때 토큰을 새로 생성하여 보내도록 하는 것이 좋을 까요? 좋은 강의 잘보고 있습니다. 감사합니다 :)
- 해결됨스프링과 JPA 기반 웹 애플리케이션 개발
generateEmailCheckToken() 의 위치!
안녕하세요~ 이메일 토큰 저장시켜주는 generateEmailCheckToken() 메소드를 트랜잭션 쓰기 전에 아에 Account를 빌더로 만들 때 넣어주면 될꺼같은데, 따로 빼서 하는 이유가 있을까요?
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
코드 말고 강의 자료는 어디서 받나요??
강의 실습 가이드의 자료 버튼을 누르면 zip파일만 받아지고 pdf는 없는데 어디서 받는건가요??
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
Validator의 Bean 등록 여부에 따른 동작 차이에 대해 질문있습니다.
Validator를 Bean으로 등록해서 자동 주입으로 받아와서 사용하는 것과 new로 선언해서 사용하는 것에 동작상의 차이가 있나요? 닉네임 수정하고 변경하기 버튼 누르면 NullPointException이 나더라구요. 에러가 나는 지점이 Validator에서 Repository 읽어오는 부분에서 에러가 발생했다고 나와요. 그래서 디버깅으로 찍어봤을땐 원하는대로 값 다 들어왔었는데 동작을 안했습니다. 일단 문제 해결은 Contorller쪽에서 NicknameValidator 사용 할 때 자동 주입으로 받아와서 사용하니깐 해결 되더라구요. 근데 Password의 Validator는 new로 선언했었구 sing-up이랑 Nickname에서는 자동 주입 사용하는데 이 두개의 동작이 이런 에러가 날정도로 차이가 존재하나요? 빈으로 등록하면 스프링 컨테이너 라이프 사이클을 사용할 수 있는 점 이외에는 동작상 차이가 없는것 아닌가요 ?
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
login 구현할때
import org.springframework.boot.autoconfigure.security.servlet.PathRequest; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception{ http.authorizeRequests() .mvcMatchers("/", "/login", "/sign-up", "/check-email-token" , "/email-login", "/check-email-login", "/login-link").permitAll() .mvcMatchers(HttpMethod.GET, "/profile/*").permitAll() .anyRequest().authenticated(); http.formLogin() .loginPage("/login").permitAll(); http.logout() .logoutSuccessUrl("/"); } ... 강의 보면서 진행했을 땐 잘 작동했는데 이후 구현하면서 에러가 발생했습니다. 로그인 수행을 하면 로그인은 되지만 /error로 redirect 되어 화면에는 아래와 같은 에러가 뜹니다. {"timestamp":"2020-04-15T14:28:16.449+0000","status":999,"error":"None","message":"No message available"} spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration 구글링하면서 위 프로퍼티를 추가하여 해결했지만 /error을 요청하지 않았는데 왜 이런 현상이 발생하는지 이해가 되지 않습니다..
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
강의 제목 철자 관련
항상 좋은 강의 서비스해주셔서 감사합니다. 강의 시청 중 강의 제목에 오탈자가 있는 것 같아 남깁니다. 폿 -> 폼 으로 수정되어야 할 것 같은데 보시고 맞다면 수정하시는게 좋을 것 같습니다. 의도하신 거라면 제 글을 삭제하겠습니다 ^^; 바이러스때문에 미국도 안전하지 않다는 뉴스를 자주 접하는데 건강 유의하시길 바래요~
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
영속 상태에 관해 질문이 있습니다.
저는 엔티티가 detached 되는 시점이 Transaction이 끝나는 시점 (@Transactional 애노테이션이 붙은 메서드의 호출 후)인 줄 알았는데 오늘 수업을 들으니 그게 아닌 것 같아요. findByEmail로 조회를 하고나면 해당 트랜잭션이 끝나 detached 상태가 되는 줄 알았거든요. 그렇다면 제가 위에 서술한 부분 중 틀린 부분이 있을건데 어느 부분을 잘못 이해하고 있는지 궁금해요 !
- 해결됨스프링과 JPA 기반 웹 애플리케이션 개발
트랜잭션
AccountService에 있는 @Transactional은 왜 무시가 된건가요?? 어플리케이션을 돌릴때는 트랜잭션 처리가 되는데, 테스트에서는 왜 또 @Transactional 을 붙여줘야 하나요?
- 해결됨스프링과 JPA 기반 웹 애플리케이션 개발
테스트시, 파라미터 질문입니다.
SignUpForm 객체를 만들어서 ObjectMapper로 json으로 변환해서 post요청을 했더니, 매핑 자체가 안되네요.. 이거는 강의에서의 성공 테스트인데, 위의 오류와 다른점은, 여기에서는 post 요청임에도 불구하고 파라미터 값들이 http body에 들어가지 않고 Parameters에 들어간다는 점 입니다. 제가 위에서 실패한 케이스는 content()에 json으로 넣었으니 당연히 http body에 json 형태로 들어가구요.. spring boot는 message converter가 json용으로 자동으로 들어가있다고 예전 spring boot 강의에서 배워서.. 근데 이번엔 좀 다르네요 ㅠ 왜 이런 결과가 나오는 건가요??
- 해결됨스프링과 JPA 기반 웹 애플리케이션 개발
자동입력 문의 드립니다.
회원가입 폼에 기본값이 들어가도록 모델객체에 기본값을 넣어주려고 합니다. @GetMappingpublic String showRegistrationForm(Model model) { AccountRegistrationDto registration = new AccountRegistrationDto(); registration.setLastName("LastName"); registration.setFirstName("FirstName"); registration.setEmail("test@test.com"); registration.setConfirmEmail("test@test.com"); registration.setPassword("User1234@"); registration.setConfirmPassword("User1234@"); registration.setTerms(true); model.addAttribute("user",registration); return "registration";} 비번을 넣는 부분은 안들어 가네요.. 왜 그런건지..
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
git alias를 만들기
https://johngrib.github.io/wiki/git-alias/
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
앞선 질문의 해답이 이곳에 있었네요
로그인 로그아웃 강의에서 질문했던 버그를 이 강의에서 다룬거같습니다
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
현재 강의 시점으로 질문있습니다.
로그아웃 구현까지 따라해보았는데 가입후 이메일 인증을 받은후 로그아웃 재로그인하면 emailVerified가 false상태로 보여집니다 다시인증을 해야한다고 나오는데 아직 구현이 안된 설정인가요 제 코드에 실수가 있는건가요??
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
개발문서 문의
안녕하세요. 강의 도중에 구글 독스로 개발 문서를 보여주시는데요. 중간중간 참고 사이트 및 참고자료를 보여주시는데, 궁금해서 영상을 보고 찾거나 지나칠때가 있습니다. 그래서 혹시 이전 강의처럼 강의 진행하실때 보셨던 문서를 올려주실수 있는지 궁금합니다. 감사합니다.
- 미해결스프링과 JPA 기반 웹 애플리케이션 개발
lombok @Builder 질문드려요
@Builder.Default를 사용하지 않는 이유가있나요??