묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
orderItem에 관한 질문입니다.
만약에 JPARepository를 사용하면 orderItemRepository도 따로 만들어서 orderItemRepository.save()를 이용하는게 맞는건가요??
-
해결됨더 자바, 코드를 조작하는 다양한 방법
CGLib를 따라 해보면서 문제점이 있으며, 해결법입니다. JDK17입니다.
JDK17을 사용하면서, `Spring`의 추가를 하지않고 진행을 하면서 보니 아래의 이미지와 같은 오류가 발생하네요.확인을 해보니, JDK16부터 Issue가 발생되었던것 같아보입니다. 제가 참고한 글은 https://github.com/cglib/cglib/issues/191 글이었습니다. 해결법은 위의 issue에 나와있는 그대로, VMOptions항목에 --add-opens java.base/java.lang=ALL-UNNAME를 추가하였습니다. 아래의 사진처럼요.혹시 실습해보고 싶은데 안되는 분들중, 유사한 오류가 나시는 분들은 참고하시기 바랍니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
변경감지를 사용하여 db 데이터 업데이터 시 sql이 2번 실행되는 것에 대한 성능
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]여기에 질문 내용을 남겨주세요.김영한님 JPA 강의를 다 듣고 개발을 하던 도중 궁금한게 생겼습니다.Entity를 변경 감지를 통해 데이터를 바꿀 시 select 쿼리를 통해 데이터를 불러오고 수정하게 되면 update 쿼리가 한번사용되어 총 2번의 sql로 데이터를 바꾸게 되는데,그냥 "update ~~~ where id = ?" 이런 식으로 데이터를 바꾸게 되면 한 번의 sql로 데이터를 바꾸니까 성능 상 더 좋은 부분이 생길수도 있나? 라는 생각을 하게됩니다. 여기서 답변 받고 싶은 부분은이 부분은 아주 미묘한 차이니까 무시하는 것인가?실제로 자주 변경되는 데이터는 성능상에 이유로 update 쿼리를 한 번만 직접 날려 처리하는 경우도 있는가? (벌크 연산제외)변경 감지로 데이터를 update하는 것의 장점들도 궁금합니다. 제가 예전에 강의를 들어서 혹시 영한님이 언급하셨는데 못 찾고 있는건가라는 생각도 들지만 궁금해서 여쭤봅니다!
-
미해결호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)
세션과 토큰을 이용한 로그인 유지 방식의 차이점
안녕하세요! 강의를 보다가 의문점이 생겨 질문드립니다.크게 아래와 같이 두 가지 질문이 생겼습니다.로그인 유지를 위해 remember-me 토큰을 발급하고 해당 토큰의 유효기간을 (예를 들어) 30일로 설정하여 유저의 세션이 만료되어도 로그인이 풀리지 않게 한다면 단순히 최초에 저장되는 세션의 유효기간을 30일로 늘리는 것과 비교해 보안 측면에서 어떠한 장점을 갖는지 의문이 들었습니다.결론적으로 만약 리프레시 토큰을 사용한다고 하면 리프레시 토큰이 만료되기 전에 이를 갱신할 책임은 클라이언트에게 있는 건가요?? DB를 사용하지 않는 remember-me 방식이라고하면 토큰에서만 expired 관련 정보를 알 수 있을 것이고 그렇다면 클라이언트에서 이를 디코딩하여 남은 유효기간을 확인 후 직접 다시 요청을 하는 식의 처리를 해서 Cookie를 갈아주어야 하는 것인가하는 생각이 들었습니다.먼저 2번의 경우 강의에서의 세션=액세스 토큰, remember-me 토큰=리프레시 토큰이라고 비슷하게 생각할 수 있을 것 같아서 카카오 api 문서를 참고해봤는데,카카오에서는 리프레시 토큰의 유효기간이 1달 이내일 경우 액새스 토큰 갱신 요청을 보낼 때 리프레시 토큰도 같이 갱신하여 보내준다고 하더라구요. (https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#refresh-token)2번의 경우 이렇게 이해하면 되는건지와, 1번에 대해서는 어떻게 생각하시는지 궁금합니다!
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
java.lang.NullPointerException: Cannot invoke because is null 이 떠요
강의를 보며 따라하면서 기존 클래스들을 변형하여 진행할 때 test 코드 작성 시 다음과 같이 에러가 뜹니다처음에는 이런 문구가 뜨고 스프링부트 3.x 를 쓰고있어서 @ExtendWith(SpringExtension.class) //junit 5 로 변경하고 나서야 다음과 같은 문구가 뜹니다.강의에서 @RequiredArgsConstructor 를 쓰면 final을 선언해줘야한다고 해서 강의와 동일하게 진행했으나 service의 join에서 null값이 생기는 것 같은데 어디가 문제인지 모르겠습니다.java.lang.NullPointerException: Cannot invoke because "this." is nullbuild.grable 은 다음과 같습니다.plugins { id 'java' id 'org.springframework.boot' version '3.0.7' id 'io.spring.dependency-management' version '1.1.0' } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies {implementation 'org.springframework.boot:spring-boot-starter-data-jpa' // implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-validation' //유효성 검증 implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' //web view implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' // runtimeOnly 'com.mysql:mysql-connector-j' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' // testImplementation 'org.springframework.security:spring-security-test' //JUnit4 추가 testImplementation("org.junit.vintage:junit-vintage-engine") { exclude group: "org.hamcrest", module: "hamcrest-core" } } test { useJUnitPlatform() } tasks.named('test') { useJUnitPlatform() }Userpackage domain; import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; import lombok.Setter; @Entity @Getter @Setter //@NotNull public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", updatable = false) private Long id; //auto increment @Column(name = "email", nullable = false) private String email; //id @Column(length = 200 ,name ="password") private String password; @Column(name = "name", nullable = false) private String name; @Column(name= "phone" ,nullable = false ) private String phone; @Builder public User(){ this.email =email; // this.name=name; } } UserRepositorypackage domain; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import org.springframework.stereotype.Repository; import java.util.List; @Repository public class UserRepository { @PersistenceContext private EntityManager em; public void save(User user){ em.persist(user); } public User findOne(String email) { //email 값으로 멤버값 반환 return em.find(User.class, email); } //리스트조회 public List<User> findAll(){ return em.createQuery("select u from User u", User.class) .getResultList(); } //특정값으로 조회 public List<User> findByName(String name) { return em.createQuery("select u fromUser u where u.name = :name", User.class) .setParameter("name", name) .getResultList(); } } UserServicepackage domain; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service @Transactional(readOnly = true) @RequiredArgsConstructor //final있는 field 로 생성자 public class UserService { private final UserRepository userRepository; // @Transactional public String join(User user){ validateDuplicateMember(user); // 중복 회원 검증 userRepository.save(user); //error : line 13 선언변수 그대로 가져와야함 return user.getEmail(); } private void validateDuplicateMember(User user){ List<User> findUsers = userRepository.findByName(user.getName()); if(!findUsers.isEmpty()) { throw new IllegalStateException("이미 존재하는 회원입니다."); } } } UserServiceTestpackage domain; import org.junit.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; import static org.junit.Assert.assertEquals; //메모리 모드 DB 연계 테스트 //@RunWith(SpringRunner.class) //junit 4 @ExtendWith(SpringExtension.class) //junit 5 @SpringBootTest @Transactional //rollback public class UserServiceTest { @Autowired UserService userService; @Autowired UserRepository userRepository; @Test public void 회원가입() throws Exception { //Given User user = new User(); user.setEmail("fitplace@naver.com"); //email 로 검증 -> name은 중복 존재 가능성 o //When String saveEmail = userService.join(user); //Then assertEquals(user, userRepository.findOne(saveEmail)); } // @Test(expected = IllegalStateException.class) // public void 중복_회원_제외() throws Exception { // //Given // // //When // // //Then // // } // }
-
해결됨Practical Testing: 실용적인 테스트 가이드
강의 내용중에 궁금한게 있습니다.
Presentation Layer 테스트 (2)0:59:00 부터 말씀해주신 내용이 대략 이렇습니다.서비스 로직이 커지게 되어 분리를 하거나 모듈화하여 사용한다면controller dto를 하위 레이어인 service에서 알고있으면필요없는 Bean Valid의 의존성을 추가해야하고, 하위레이어가 상위 레이어에 의존성이 생기게 되어 해당 서비스 로직을 다른 컨트롤러에서 사용하고 싶을때 발목을 잡는다.라고 말씀해주셨습니다. 전제 : 확장할 일도 없고, 이 서비스는 해당 컨트롤러에서만 사용하게 되는 구조일 경우Service용 Dto를 만들지 않고 Controller Dto에서 Entity로 변환해서 Service에 넣어주시나요 ?아니면 코드의 일관성을 생각해서 몇분 안걸리니까 만들어서 사용하시나요? 그리고 추가로 궁금한게 있습니다.service 패키지가 api 패키지 내에 존재하는데서비스가 확장되고 모듈화가 되어 사용한다거나 ,다른 컨트롤러에서도 그 서비스를 사용하게 된다면서비스 패키지는 도메인 패키지쪽으로 넣어서api (controller,advice,advice dto),domain( entity(entity,repository), service(service,dto)) 같은 구조로 변경을 하시는지 궁금합니다.그리고 현재 프로젝트에서 api 패키지 안에 service 패키지를 넣으신 이유도 궁금합니다. !! 질문의 영역을 벗어났다는 것을 알지만, 답변을 해주실 수 있으실까요 감사합니다(__)신뢰할만한 답변을 받을 곳이 없어서 질문을 남겨봅니다..답변하시기 어려우시다면 키워드라도 알려주시면 감사합니다!!
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
양방향 괸계에서 관계 설정 위치에 대한 질문이 있습니다.
회원 - 주문 관계에서 관계를 설정할 때는 주문 엔티티에서 public void setMember(Member member) { this.member = member; member.getOrders().add(this); }이렇게 관계를 설점함과 동시에 주문- 주문상품 -상품 관계를 설정할 때도 주문 엔티티에서 관계를 설정하더라구요public void addOrderItem(OrderItem orderitem){orderItems.add(orderitem);orderitem.setOrder(this);}이 과정은 어느 엔티티에 하던 상관 없는건가요?
-
해결됨Practical Testing: 실용적인 테스트 가이드
테스트코드에서만 적용되는 yml 설정을 하고 싶습니다.
안녕하세요! 실무에서 겪었던 문제에 대한 조언을 구하고 싶습니다.test 하위에 application.yml을 만들면 테스트코드 돌릴 때 해당 yml 설정을 따른다고 배워서 적용했습니다. application-local.ymlapplication-prod.yml이런 식으로 뒤에 - 프로필이 붙은 형태이고테스트 폴더 하위에도application-local.yml파일을 만들었습니다. DB 연결이 안되길래 prod.yml 쪽으로 연결 시도를 하는거 같아테스트 코드에@ActiveProfiles("local")을 붙여주었고 테스트 서버 DB에 잘 붙어서 테스트코드를 작성했습니다.(main/applicatino-local.yml 역시 테스트 서버 DB에 연결되어 있는 상태)테스트코드를 작성하다보니 이게 불편하더라구요그래서 h2 인메모리 DB를 사용하고자 테스트 코드용 yml에 설정을 해주었습니다.jpa ddl auto 설정도 create 였구요..ㅎㅎㅎ 동료 개발자분이 테스트 서비스 로그인이 안된다길래 보니 테스트 디비 데이터가 다 날아갔습니다,,,하하하하정말 식은땀이 주륵..... 다행히 얼마 전에 다른 작업으로 백업을 해둔게 있어서 그걸로 복구했습니다만 정말 아찔했습니다 ㅠㅠ main/appication-local.yml 의 datasource url로 연결하고test/appication-local.yml 의 ddl-auto: create 설정을 따른 것으로 보여지는데왜 이런걸까요?저는 test/appication-local.yml 설정만 따를 거라고 생각했는데.. 제가 원하는 것은 local에서 서버를 직접 띄워서 사용할 때는 test 서버 db에 연결하고 싶고테스트 코드 돌릴 때는 인메모리 h2를 사용하고 싶습니다.이런 경우에 어떻게 사용하면 좋을까요? main/applilcation-local.ymldatssource: 테스트 서버 DB test/applilcation-local.ymldatssource: 인메모리 h2 DBjpa ddlauto: create -> 테스트 서버 디비 데이터 다 날아감내가 원하는 것 : 테스트 코드는 test/applilcation-local.yml 설정만을 따라 인메모리 DB 사용
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
main/application.yml, test/application.yml
안녕하세요! 실무에서 겪었던 문제에 대한 조언을 구하고 싶습니다.강의를 들으며 test 하위에 application.yml을 만들면 테스트코드 돌릴 때 해당 yml 설정을 따른다고 배워서 적용했습니다. application-local.ymlapplication-prod.yml이런 식으로 뒤에 - 프로필이 붙은 형태이고테스트 폴더 하위에도application-local.yml파일을 만들었습니다. DB 연결이 안되길래 prod.yml 쪽으로 연결 시도를 하는거 같아테스트 코드에@ActiveProfiles("local")을 붙여주었고 테스트 서버 DB에 잘 붙어서 테스트코드를 작성했습니다.(main/applicatino-local.yml 역시 테스트 서버 DB에 연결되어 있는 상태)테스트코드를 작성하다보니 이게 불편하더라구요그래서 h2 인메모리 DB를 사용하고자 테스트 코드용 yml에 설정을 해주었습니다.jpa ddl auto 설정도 create 였구요..ㅎㅎㅎ 동료 개발자분이 테스트 서비스 로그인이 안된다길래 보니 테스트 디비 데이터가 다 날아갔습니다,,,하하하하정말 식은땀이 주륵..... 다행히 얼마 전에 다른 작업으로 백업을 해둔게 있어서 그걸로 복구했습니다만 정말 아찔했습니다 ㅠㅠ main/appication-local.yml 의 datasource url로 연결하고test/appication-local.yml 의 ddl-auto: create 설정을 따른 것으로 보여지는데왜 이런걸까요?저는 test/appication-local.yml 설정만 따를 거라고 생각했는데.. 제가 원하는 것은 local에서 서버를 직접 띄워서 사용할 때는 test 서버 db에 연결하고 싶고테스트 코드 돌릴 때는 인메모리 h2를 사용하고 싶습니다.이런 경우에 어떻게 사용하면 좋을까요? main/applilcation-local.ymldatssource: 테스트 서버 DB test/applilcation-local.ymldatssource: 인메모리 h2 DBjpa ddlauto: create -> 테스트 서버 디비 데이터 다 날아감내가 원하는 것 : 테스트 코드는 test/applilcation-local.yml 설정만을 따라 인메모리 DB 사용
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
onetoone 페치전략 설정 질문입니다
0:21 에 @ManyToOne 과 @OneToOne은 기본이 즉시로딩이므로 지연로딩으로 변경하라는 설명입니다.제가 궁금한것은 @OneToOne 단방향은 jpa에서 지원이 안되고 양방향으로 설정해야하고 이때 지연로딩으로 설정하거나 아예 설정자체를 하지않아도 기본적으로 즉시로딩으로 된다고 알고있는데 제가 잘못알고있는건가요?=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.
-
미해결실전! 스프링 데이터 JPA
단방향 연관관계 적용시 질문 있습니다.
일반적으로 양방향 연관관계는 지양하는 것이 좋다고 해서, 단방향 연관관계로 생각을 해보고 있는데요. Member (N) 쪽에만 Team 쪽으로 단방향 연관관계를 설정한 상태인데요. 특정 팀의 멤버들을 알고 싶은 경우가 있을거 같아요. Member 중, team id 가 X 인 것을 찾고 싶은 경우에는 어떻게 해야하나요? fetch join 시에는 별칭을 줄 수 없기 때문에 안될거 같습니다. 이럴때는 그냥 일반 조인문으로 풀어내고, team 정보가 필요하다면 다시 조회하는 것이 맞나요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
처음 DB 설정 후 테스트를 하는 부분에서 오류가 발생합니다.
프로젝트 압축 링크https://drive.google.com/file/d/1xah6ydIWZ1kN-mzwr3-aPRF3Xm9WpRkw/view?usp=sharing 전체 오류 내용은 다음과 같습니다.java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@7df4709e testClass = jpabook.jpashop.MemberRepositoryTest, locations = [], classes = [jpabook.jpashop.JpashopApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@29e495ff, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@a3d8174, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@120f102b, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@247d8ae, org.springframework.boot.test.context.SpringBootTestAnnotation@6e0b0ab3], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:143)at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:127)at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:241)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)at org.junit.runners.ParentRunner.run(ParentRunner.java:413)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)at org.junit.runner.JUnitCore.run(JUnitCore.java:137)at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not instantiate id generator [entity-name=jpabook.jpashop.Member]at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1770)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520)at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:931)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608)at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734)at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:436)at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1406)at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:545)at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:187)at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:119)... 27 moreCaused by: jakarta.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not instantiate id generator [entity-name=jpabook.jpashop.Member]at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421)at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1816)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1766)... 48 moreCaused by: org.hibernate.MappingException: Could not instantiate id generator [entity-name=jpabook.jpashop.Member]at org.hibernate.id.factory.internal.StandardIdentifierGeneratorFactory.createIdentifierGenerator(StandardIdentifierGeneratorFactory.java:230)at org.hibernate.id.factory.internal.IdentifierGeneratorUtil.createLegacyIdentifierGenerator(IdentifierGeneratorUtil.java:126)at org.hibernate.mapping.SimpleValue.createGenerator(SimpleValue.java:414)at org.hibernate.internal.SessionFactoryImpl.lambda$createGenerators$1(SessionFactoryImpl.java:413)at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)at java.base/java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1779)at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)at org.hibernate.internal.SessionFactoryImpl.createGenerators(SessionFactoryImpl.java:412)at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:249)at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:431)at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1455)at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75)at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376)at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)... 52 moreCaused by: org.hibernate.HibernateException: Could not fetch the SequenceInformation from the databaseat org.hibernate.engine.jdbc.env.internal.ExtractedDatabaseMetaDataImpl.sequenceInformationList(ExtractedDatabaseMetaDataImpl.java:307)at org.hibernate.engine.jdbc.env.internal.ExtractedDatabaseMetaDataImpl.getSequenceInformationList(ExtractedDatabaseMetaDataImpl.java:151)at org.hibernate.id.enhanced.SequenceStyleGenerator.getSequenceIncrementValue(SequenceStyleGenerator.java:568)at org.hibernate.id.enhanced.SequenceStyleGenerator.configure(SequenceStyleGenerator.java:216)at org.hibernate.id.factory.internal.StandardIdentifierGeneratorFactory.createIdentifierGenerator(StandardIdentifierGeneratorFactory.java:224)... 71 moreCaused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "start_value" not found [42122-214]at org.h2.message.DbException.getJdbcSQLException(DbException.java:502)at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)at org.h2.message.DbException.get(DbException.java:223)at org.h2.message.DbException.get(DbException.java:199)at org.h2.jdbc.JdbcResultSet.getColumnIndex(JdbcResultSet.java:3492)at org.h2.jdbc.JdbcResultSet.getLong(JdbcResultSet.java:745)at com.zaxxer.hikari.pool.HikariProxyResultSet.getLong(HikariProxyResultSet.java)at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.resultSetStartValueSize(SequenceInformationExtractorLegacyImpl.java:110)at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.lambda$extractMetadata$0(SequenceInformationExtractorLegacyImpl.java:54)at org.hibernate.tool.schema.extract.spi.ExtractionContext.getQueryResults(ExtractionContext.java:50)at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.extractMetadata(SequenceInformationExtractorLegacyImpl.java:39)at org.hibernate.engine.jdbc.env.internal.ExtractedDatabaseMetaDataImpl.sequenceInformationList(ExtractedDatabaseMetaDataImpl.java:291)... 75 more 1년전 수강 완료한 강의지만 다시 듣는 과정에서 오류가 발생한거라작년 코드와 비교도 해보고 구글링을 통해 build.gradle이나 application.yml에 문제가 있는 것 같다고 생각했지만아직 해결하지 못했습니다. 현재 제 applicaiton.yml 이고build.gradle 입니다plugins {id 'java'id 'org.springframework.boot' version '3.1.1'id 'io.spring.dependency-management' version '1.1.0'}group = 'jpabook'version = '0.0.1-SNAPSHOT'java {sourceCompatibility = '17'}configurations {compileOnly {extendsFrom annotationProcessor}}repositories {mavenCentral()}dependencies {implementation 'org.springframework.boot:spring-boot-starter-data-jpa'implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'implementation 'org.springframework.boot:spring-boot-starter-web'implementation 'org.springframework.boot:spring-boot-devtools'implementation group: 'org.javassist', name: 'javassist', version: '3.15.0-GA' //test코드 오류나서 추가testImplementation 'junit:junit:4.13.1'compileOnly 'org.projectlombok:lombok'runtimeOnly 'com.h2database:h2'annotationProcessor 'org.projectlombok:lombok'testImplementation 'org.springframework.boot:spring-boot-starter-test'testImplementation("org.junit.vintage:junit-vintage-engine") {exclude group: "org.hamcrest", module: "hamcrest-core"}}tasks.named('test') {useJUnitPlatform()}
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
em.find의 궁금점
안녕하세요. 공부를 하다가 궁금증이 생겨 남깁니다.위와 같은 코드를 실행했을 때 영속성 컨텍스트가 비어 있기에 아무것도 반환하지 못하는 것이라고 이해했는데 그렇다면 print가 찍히지 않는 이유는 무엇인가요? try catch로 nullpointerException인지 확인해봤는데 null은 아닌 것 같아서 문의 남깁니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
PPT 내용 중, DB 관계 그림 질문있습니다.
위 그림 1:N 관계에서 어떤 쪽은 삼각형에 동그라미가 붙어있고 어떤 쪽은 안붙어있는데 차이가 뭔가요?? 감사합니다.
-
해결됨실전! Querydsl
이런식으로 sort 적용하는 것도 문제가 없을까요?
OrderSpecifier 클래스를 사용해서 정렬을 적용해보려 했으나블로그 글마다 너무다 제각각이고 상세한 설명을 찾기가 힘들어방법을 고민하던 중 다음과 같은 방법으로 정렬을 적용해서 postman으로 get 요청을 해보니 정상적으로 정렬이 동작하는 것을 확인했는데요.제가 적용한 방법을 설명하면 다음과 같습니다.- 요청 응답 구조는 강의와 같이 controller <-> Repository 구조로 만들었습니다.먼저 컨트롤러가 /search로 Get 요청을 받으면 Repository에서 MemberTeamDto가 아닌 Member 엔티티를 반환받고 컨트롤러에서 MemberTeamDto로 변환하여 반환하였습니다.이런식으로 해서 요청을 하니 제가 적용한 나이 기준 내림차순이 적용되는 것을 확인했는데이 방법으로 정렬을 적용해도 문제가 없을까요 ?? controller @GetMapping("/search") public Page<MemberTeamDto> searchPageOrder(MemberSearchCondition condition, Pageable pageable) { Page<Member> members = memberRepository.searchPageOrder(condition, pageable); List<MemberTeamDto> content = members.getContent().stream() .map(member -> new MemberTeamDto( member.getId(), member.getUsername(), member.getAge(), (member.getTeam() != null) ? member.getTeam().getId() : null, (member.getTeam() != null) ? member.getTeam().getName() : null) ) .collect(Collectors.toList()); return new PageImpl<>(content, pageable, members.getTotalElements()); } Repository @Override public Page<Member> searchPageOrder(MemberSearchCondition condition, Pageable pageable) { List<Member> content = queryFactory .selectFrom(member) .leftJoin(member.team, team) .where(usernameEq(condition.getUsername()), teamNameEq(condition.getTeamName()), ageGoe(condition.getAgeGoe()), ageLoe(condition.getAgeLoe())) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .orderBy(member.age.desc()) // orderBy를 사용한 id 기준 내림차순 정렬 .fetch(); JPAQuery<Long> countQuery = queryFactory .select(member.count()) .from(member) .leftJoin(member.team, team) .where(usernameEq(condition.getUsername()), teamNameEq(condition.getTeamName()), ageGoe(condition.getAgeGoe()), ageLoe(condition.getAgeLoe())); return PageableExecutionUtils.getPage(content, pageable, () -> countQuery.fetchOne()); }
-
미해결실전! 스프링 데이터 JPA
data jpa 사용 시 쿼리도 aop 같은 방식이 적용 가능한가요?
안녕하세요. 강의 듣고, jpa이용해서 팀 프로젝트 만들어 보고 있습니다.다름이 아니라, 게시글 삭제 시, 정말 게시글이 삭제되는 것이 아니라, 게시글 안의 Enum 에 deleted로 변경 해 두고, 일정 시간이 삭제되게 하려고 했습니다.변경 까지는 문제가 없었는데, 이렇게 기능이 추가가 되니, 기존에 게시 글을 반환하던 쿼리 들에 전부where status = 'ACTIVE' 와 같은 조건을 넣어주어야 하게 되었습니다. 전부 수작업으로.... 조건을 넣어주는 방법 밖에는 없을까요? 간단한 프로젝트라고 생각해서 QueryDsl은 사용하지 않았습니다.또 저 조건을 개발자가 전부 쿼리 개발 할 때 필수로 넣어야 된다면, 어쩌다 까먹고 안 넣게되면 삭제 처리 되었던 게시글이 사용자 눈에 보이는..참사가 발생할 것 같습니다.기존 Repository 쿼리가 실행되기 전에 먼저 article.status = 'ACTIVE' 인 것들만 필터를 하고, 거기에 제가 지금까지 만들어 놓은 쿼리들이 적용이 되면 될 것 같은데, 아무리 찾아봐도 좋은 대안이 보이지가 않아 보여서 혹시나 하는 마음에 질문 드립니다.감사합니다.
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
orderItems 에 null이 들어가는 이유가 궁금합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]강의를 듣다 의문점이 생겨 질문 드립니다.OrderDto는 JPA에서 생성된 객체가 아니고 직접 생성자로 만들어서 사용한 객체인데 왜 Hibernate5Module이 프록시 객체로 생각해서 null값을 반환하는지 모르겠습니다.제가 긴시간 찾아보면서 생각한 이유는 이렇습니다.강의 5분경 쯤에 api 호출시 Json에서 orderItems 가 null로 반환되는것을 보여주십니다.orderItems가 null로 반환되는것은 스프링이 string으로 응답을 보낼때 messageConverter가 json으로 변환해서 반환을합니다.이때 orderItems가 JPA(Hibernate)에서 만든 프록시 객체로 되어있어 전강의에서 설정한 Hibernate5Module이 프록시 객체를 null로 바꾸기 때문에 orderItems가 null로 나타낸것으로 생각됩니다.하지만 제가 디버깅 모드로 확인해본 결과 OrderDto안에 있는 orderItems는 프록시 객체가 아닌 실제로 생성된 객체였습니다.(OrderDto는 단순히 JPA가 관리 하지 않아서 당연하다고 생각합니다.)강의 기준으로 orderItems 안에 있는 orderItem객체가 2개 존재하는데 orderItem객체는 JPA를 통해 생성된 객체이고 자세히 살펴보면 orderItem 안에 Item은 LAZY로딩으로 프록시 객체가 생성되어있습니다. 혹시몰라 Hibernate5Module을 끄고 실행한 결과 Item이 @JsonIgnore가 있으면 orderItems가 제대로 결과 값이 나오고 @JsonIgnore이 없으면 프록시 객체를 Json으로 변환하지 못해서 오류가 발생합니다.그럼 Hibernate5Module는 엔티티 안에 객체의 값중 하나라도 프록시 객체가 있다면 다른 객체의 값이 있든 말든 그냥 null을 반환하는 걸까요??제가 이해한것이 맞는지 궁금해서 질문드립니다.긴글 읽어주셔서 감사합니다.
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
안녕하세요. 커리큘럼 관련 질문 하나만 드리겠습니다!
안녕하세요. 더운 날씨에 고생 많으십니다.다름이 아니라, 가장 최근에 영한쌤 유튜브 채널에 올라온 영상을 보면스프링 기본편 -> MVC1,2편 -> DB1,2편을 수강하고, 야생형 코스로 넘어와 JPA활용1편을 내용이 이해되지 않더라도 코드를 따라친다는 생각으로 강의를 듣고,그 다음에 JPA 기본편으로 넘어가서 공부한뒤 다시 JPA활용 1편으로 넘어와 공부를 하라고 말씀해주셨었는데요.요약하자면, 코드만 따라친다는 생각으로 JPA활용 1편 -> JPA 기본 -> 다시 JPA활용1편 복습. 이런식으로요!근데 JPA활용1편 강의 도중에 "연관관계 매핑 분석" 부분에서 이 내용이 이해가 안된다면 반드시 JPA 기본편을 다시 수강하고 오시라고 말씀하시더라구요.. 당연히 배우지 않은 내용이라 이해가 안됐습니다..!그냥 가장 최근에 올라온 영한쌤 유튜브 영상처럼 일단 코드만 따라친다는 생각으로 JPA활용1편을 완강하면 되는걸까요?
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
SQLSyntaxErrorException 에러가 나옵니다.ㅠㅠ
서버 실행 후 이름, 나이 작성하고 등록을 하려는데 '서버내부 오류가 생겼다' 라는 팝업창이 뜨면서 아래와 같은 오류가 나옵니다.ㅠㅠ 혹시 인코딩 문제일까요..? java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSET INTO user (name, age) VALUES ('���ڵ�', 25)' at line 1
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
order-service orderId문제
"not-null property references a null or transient value : com.example.orderservice.jpa.OrderEntity.orderId; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : com.example.orderservice.jpa.OrderEntity.orderId"이 오류는 com.example.orderservice.jpa.OrderEntity 클래스의 orderId 속성이 null 또는 임시 값으로 설정되어 있을 때 발생합니다. 즉, orderId 속성에는 null이 허용되지 않는데, null이나 임시 값으로 설정되었기 때문에 오류가 발생합니다.application.ymlserver: port: 0 spring: application: name: order-service h2: console: enabled: true settings: web-allow-others: true path: /h2-console sql: init: mode: always jpa: database-platform: org.hibernate.dialect.H2Dialect hibernate: ddl-auto: update properties: hibernate: format_sql: true show_sql: true defer-datasource-initialization: true datasource: driver-class-name: org.h2.Driver url: jdbc:h2:mem:testdb main: allow-bean-definition-overriding: true eureka: instance: instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}} client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://127.0.0.1:8761/eureka logging: level: com.example.orderservice: DEBUG OrderEntity@Data @Entity @Table(name = "orders") public class OrderEntity implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false, length = 120, unique = true) private String productId; @Column(nullable = false) private Integer qty; @Column(nullable = false) private Integer unitPrice; @Column(nullable = false) private Integer totalPrice; @Column(nullable = false) private String userId; @Column(nullable = false, unique = true) private String orderId; @Column(nullable = false, updatable = false, insertable = false) @ColumnDefault(value = "CURRENT_TIMESTAMP") private Date createAt; } OrderDto@Data public class OrderDto implements Serializable { private String productId; private Integer qty; private Integer unitPrice; private Integer totalPrice; private String orderId; private String userId; } ResponseOrder@Data @JsonInclude(JsonInclude.Include.NON_NULL) public class ResponseOrder { private String productId; private Integer qty; private Integer unitPrice; private Integer totalPrice; private Date createAt; private String orderId; } OrderServicepublic interface OrderService { OrderDto createOrder(OrderDto orderDetails); OrderDto getOrderByOrderId(String orderId); Iterable<OrderEntity> getOrdersByUserId(String userId); } OrderServiceImpl@Service public class OrderServiceImpl implements OrderService{ OrderRepository orderRepository; @Autowired public OrderServiceImpl(OrderRepository orderRepository){ this.orderRepository = orderRepository; } @Override public OrderDto createOrder(OrderDto orderDto){ orderDto.setUserId(UUID.randomUUID().toString()); orderDto.setTotalPrice(orderDto.getQty() * orderDto.getUnitPrice()); ModelMapper mapper = new ModelMapper(); mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); OrderEntity orderEntity = mapper.map(orderDto, OrderEntity.class); orderRepository.save(orderEntity); OrderDto returnValue = mapper.map(orderEntity, OrderDto.class); return returnValue; } @Override public OrderDto getOrderByOrderId(String orderId) { OrderEntity orderEntity = orderRepository.findByOrderId(orderId); OrderDto orderDto = new ModelMapper().map(orderEntity, OrderDto.class); return orderDto; } @Override public Iterable<OrderEntity> getOrdersByUserId(String userId) { return orderRepository.findByUserId(userId); } }OrderController@RestController @RequestMapping("/order-service") public class OrderController { Environment env; OrderService orderService; @Autowired public OrderController(Environment env, OrderService orderService) { this.env = env; this.orderService = orderService; } @GetMapping("/health_check") public String status(){ return String.format("It's Working in Order Service on PORT %s", env.getProperty("local.server.port")); } // http://127.0.0.1:0/order-service/{user_id}/orders/ @PostMapping("/{userId}/orders") public ResponseEntity<ResponseOrder> createOrder(@PathVariable("userId") String userId, @RequestBody RequestOrder orderDetails){ ModelMapper mapper = new ModelMapper(); mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); OrderDto orderDto = mapper.map(orderDetails, OrderDto.class); orderDto.setUserId(userId); OrderDto createOrder = orderService.createOrder(orderDto); ResponseOrder responseOrder = mapper.map(createOrder, ResponseOrder.class); return ResponseEntity.status(HttpStatus.CREATED).body(responseOrder); } @GetMapping("/{userId}/orders") public ResponseEntity<List<ResponseOrder>> getOrder(@PathVariable("userId") String userId){ Iterable<OrderEntity> orderList = orderService.getOrdersByUserId(userId); List<ResponseOrder> result = new ArrayList<>(); orderList.forEach(v -> { result.add(new ModelMapper().map(v, ResponseOrder.class)); }); return ResponseEntity.status(HttpStatus.OK).body(result); } } 다 똑같이 쳤는데 뭐가 문제일까요?