묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨스프링과 JPA 기반 웹 애플리케이션 개발
패스워드 수정 시 '현재 패스워드'를 추가로 인증시키는 방법에 대한 질문입니다.
안녕하세요. '패스워드 수정' 강의와 해당 강의에 등록된 질문(https://www.inflearn.com/questions/302863)을 통해 회원의 패스워드 수정 시 '현재 패스워드'를 추가로 인증시키도록 코드를 변경하던 중 옳바른 개발 방법(?)에 대해 질문드립니다. 우선 패스워드 변경 View에서 '현재 패스워드'를 입력할 수 있도록 'input[type="password"]' 태그를 추가하고, PasswordForm(DTO 역할) 클래스에 'oldPassword'라는 프로퍼티를 추가했습니다. 이후 제가 하고자 하는 것은 패스워드 변경 유효성 검사를 하기 위해 생성했었던 PasswordFormValidator 클래스에서 View에서 입력받은 '현재 패스워드 값'과 'DB에 저장된 회원의 현재 패스워드 값'을 비교하여 일치하지 않는다면 Custom한 Error 메시지를 View로 전달해주고 싶은 상황입니다. 여기서 고민되는 것은 '패스워드 변경 Form' 요청 핸들러 메소드에서는 현재 인증된 회원 정보를 Model에 담아주고 있기 때문에 View쪽에 'input[type="hidden"]' 태그를 추가한 뒤 회원의 이메일, 닉네임 값을 설정하고 패스워드 변경 요청 시 PasswordForm 클래스에 그 값이 바인딩 될 수 있도록 아래와 같이 이메일, 닉네임 프로퍼티를 추가하여 PasswordFormValidator 클래스에서 DB에 저장된 회원의 현재 패스워드 값을 비교해서 틀린 경우 Error를 생성해 줄 것인가 아니면 이를 Validator가 아닌 '패스워드 변경 비즈니스 로직'에서 할 것인가입니다. 만약, 비즈니스 로직에서 현재 비밀번호에 대한 유효성 검증을 진행하는 경우 PasswordForm 클래스에 굳이 필요 없는 email, nickname 프로퍼티를 추가하지 않아도 되는데요. 이 두가지 방법 중 어떤 경우가 좀 더 효율적인지, 제가 생각하지 못한 방법이 또 있는지(비슷한 상황들에 대한 노하우) 조언 부탁드리겠습니다. 미리 답변 감사합니다. 아래는 PasswordFormValidator을 통해 현재 패스워드 유효성 검사를 진행할 경우에 대한 예시 코드입니다.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
grouping과 Collectors.toList의 차이가 무엇이고 emtrySet()은 무슨 기능인가요?
grouping과 Collectors.toList의 차이가 무엇이고 emtrySet()은 무슨 기능인가요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
생성자 에러 발생합니다.
안녕하세요. 잘 작동하고 있는데, 클래스명부분에 빨간줄과 함께 에러 문구가 뜨더라구요. 혹시 무시해도 되는 에러인지 궁금해서 질문드립니다. 아래에 소스코드, 발생에러, 테이블 생성 여부 올렸습니다. - 에러코드: Class 'Order' should have [public, protected] no-arg constructor - Order 코드: @Entity@Table(name="ORDERS")public class Order { @Getter @Setter @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "ORDER_ID") private Long id; @Getter @Setter @Column(name="MEMBER_ID") private Long memberId; @Getter @Setter @Transient private int discountPrice; private LocalDateTime orderDate; @Enumerated(EnumType.STRING) @Getter @Setter private OrderStatus status; public Order(Long memberId, Integer discountPrice) { this.memberId = memberId; this.discountPrice = discountPrice; } @Override public String toString() { return "Order{" + "memberId=" + memberId + ", discountPrice=" + discountPrice + '}'; }}- Orders Table log
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
안녕하세요. flush 관련 질문드립니다
안녕하세요 만약 영속성 컨텍스트의 쓰기 지연 SQL 저장소에 insert 문이 5개가 있는 상태에서 flush 한다면 5번의 insert sql과 1번의 커밋으로 총 6번을 데이터베이스와 통신하는 건가요? 아니면 5개 전부 한꺼번에 날리고 + 1번의 커밋으로 총 2번을 데이터베이스와 통신하는 건가요? (아니면 JDBC 의 SQL 배치 기능을 이용해야만 총 6번의 통신을 2번의 통신으로 줄일 수 있는 건가요?) 감사합니다
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
회원과 주문의 양방향 연관관계가 실무에서는 주문이 회원을 참조하는 것으로 충분하다면
아무래도 회원과 주문이 존재한다면 주문 내역 조회같은 로직이 거의 포함된다고 생각합니다! 이럴 때는 양방향 매핑 관계를 통해 조회하는 것이 좋은지, 아니면 주문 테이블에서 member.getId()로 select 쿼리문을 날려서 조회하는 것이 좋은지 궁금합니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
hibernate:drop table member if exists 오류
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 이렇게 오류가 발생합니다! "C:\Program Files\Java\jdk-11.0.14\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.3.3\lib\idea_rt.jar=59490:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Users\하늬하루\OneDrive - SangMyung University\바탕 화면\이 찬\스프링\JPA\ex1hellojpa\target\classes;C:\Users\하늬하루\.m2\repository\org\hibernate\hibernate-entitymanager\5.3.10.Final\hibernate-entitymanager-5.3.10.Final.jar;C:\Users\하늬하루\.m2\repository\org\jboss\logging\jboss-logging\3.3.2.Final\jboss-logging-3.3.2.Final.jar;C:\Users\하늬하루\.m2\repository\org\hibernate\hibernate-core\5.3.10.Final\hibernate-core-5.3.10.Final.jar;C:\Users\하늬하루\.m2\repository\org\javassist\javassist\3.23.2-GA\javassist-3.23.2-GA.jar;C:\Users\하늬하루\.m2\repository\antlr\antlr\2.7.7\antlr-2.7.7.jar;C:\Users\하늬하루\.m2\repository\org\jboss\jandex\2.0.5.Final\jandex-2.0.5.Final.jar;C:\Users\하늬하루\.m2\repository\com\fasterxml\classmate\1.3.4\classmate-1.3.4.jar;C:\Users\하늬하루\.m2\repository\javax\activation\javax.activation-api\1.2.0\javax.activation-api-1.2.0.jar;C:\Users\하늬하루\.m2\repository\org\dom4j\dom4j\2.1.1\dom4j-2.1.1.jar;C:\Users\하늬하루\.m2\repository\org\hibernate\common\hibernate-commons-annotations\5.0.4.Final\hibernate-commons-annotations-5.0.4.Final.jar;C:\Users\하늬하루\.m2\repository\javax\persistence\javax.persistence-api\2.2\javax.persistence-api-2.2.jar;C:\Users\하늬하루\.m2\repository\net\bytebuddy\byte-buddy\1.9.5\byte-buddy-1.9.5.jar;C:\Users\하늬하루\.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\하늬하루\.m2\repository\com\h2database\h2\2.1.212\h2-2.1.212.jar;C:\Users\하늬하루\.m2\repository\javax\xml\bind\jaxb-api\2.3.0\jaxb-api-2.3.0.jar" hellojpa.JpaMain7월 14, 2022 12:51:28 오후 org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformationINFO: HHH000204: Processing PersistenceUnitInfo [ name: hello ...]7월 14, 2022 12:51:28 오후 org.hibernate.Version logVersionINFO: HHH000412: Hibernate Core {5.3.10.Final}7월 14, 2022 12:51:28 오후 org.hibernate.cfg.Environment <clinit>INFO: HHH000206: hibernate.properties not found7월 14, 2022 12:51:28 오후 org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>INFO: HCANN000001: Hibernate Commons Annotations {5.0.4.Final}7월 14, 2022 12:51:29 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configureWARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)7월 14, 2022 12:51:29 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreatorINFO: HHH10001005: using driver [org.h2.Driver] at URL [jdbc:h2:tcp://localhost/~/test]7월 14, 2022 12:51:29 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreatorINFO: HHH10001001: Connection properties: {user=sa}7월 14, 2022 12:51:29 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreatorINFO: HHH10001003: Autocommit mode: false7월 14, 2022 12:51:29 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init>INFO: HHH000115: Hibernate connection pool size: 20 (min=1)7월 14, 2022 12:51:29 오후 org.hibernate.dialect.Dialect <init>INFO: HHH000400: Using dialect: org.hibernate.dialect.H2DialectHibernate: drop table Member if existsHibernate: create table Member ( id bigint not null, name varchar(255), primary key (id) )7월 14, 2022 12:51:29 오후 org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnectionINFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@523d6bdb] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.7월 14, 2022 12:51:29 오후 org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnectionINFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@74294c1a] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.7월 14, 2022 12:51:29 오후 org.hibernate.tool.schema.internal.SchemaCreatorImpl applyImportSourcesINFO: HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@7479b626'7월 14, 2022 12:51:30 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stopINFO: HHH10001008: Cleaning up connection pool [jdbc:h2:tcp://localhost/~/test]7월 14, 2022 12:51:30 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections closeERROR: Connection leak detected: there are 1 unclosed connections upon shutting down pool jdbc:h2:tcp://localhost/~/test
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
gradle 로 수업을 따라했을 때 문제가 발생해 질문남깁니다.
안녕하세요. gradle로 실습을 진행하다가 Entity 경로를 찾지 못하는 문제가 발생해서 질문 드립니다. 주제는 다음과 같습니다. persist 로 영속성 컨텍스트에 저장하려고 하는데 에러를 따라가보니 Entity 경로를 못찾는 에러가 발생했습니다. 그래서 persistence.xml 에 <class> 태그로 경로를 설정해줌으로써 에러는 해결되었습니다. 그런데 질문사항은 다음과 같습니다. 이렇게 해결하는 방식이 맞는 해결 방식일까요? gradle로 진행시 application.properties로 설정하는 방식을 사용하는게 나을까요?? <?xml version="1.0" encoding="UTF-8" ?><persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1"> <persistence-unit name="5xik"> <class>xik.ShoppingMall.Domain.Member</class> <properties> <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/> <property name="javax.persistence.jdbc.user" value="sa"/> <property name="javax.persistence.jdbc.password" value=""/> <property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/jpashop"/> <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true"/> <property name="hibernate.use_sql_comments" value="true"/> <!--property name="hibernate.id.new_generator_mappings" value="true"/--> </properties> </persistence-unit></persistence>package xik.ShoppingMall;import lombok.Getter;import lombok.Setter;import org.junit.jupiter.api.Test;import xik.ShoppingMall.Domain.Member;import javax.persistence.*;public class JpaTest{ @Test void JpaTest() { // 엔티티 팩토리 생성 EntityManagerFactory emf = Persistence.createEntityManagerFactory("5xik"); // 엔티티 매니저 생성 EntityManager em = emf.createEntityManager(); // 트랜잭션 객체 생성 EntityTransaction tx = em.getTransaction(); tx.begin(); Member membertest = new Member(); //membertest.setId(1L); membertest.setName("parksung"); membertest.setPhoneNumber("01074724537"); em.persist(membertest); try{ Member findMember = em.find(Member.class, 1L); System.out.println("findMember,Id = " + findMember.getId()); System.out.println("findMember.Name = " + findMember.getName()); tx.commit(); } catch(Exception e){ tx.rollback(); } finally{ em.close(); } emf.close(); }}package xik.ShoppingMall.Domain;import lombok.Getter;import lombok.Setter;import javax.persistence.*;@Entity@Table(name="MEMBER")public class Member { @Getter @Setter @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 시스템에 저장하기 위해 시스템이 정하는 변수 @Getter @Setter @Column(name="name") private String name; // 고객이 입력한 데이터 @Getter @Setter @Column(name="phonenumber") private String phoneNumber; // 휴대폰 번호 @Getter @Setter @Enumerated(EnumType.STRING) @Column(name="grade") private Grade grade;}
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
상품 주문시 에러가 발생합니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : jpabook.jpashop.domain.Order.delivery -> jpabook.jpashop.domain.Delivery 어떤 부분에서 문제가 생기는지 못찾아서 전체 파일 첨부합니다.. https://drive.google.com/drive/folders/1I0oUU741fn4nApLLQ-e_16pY0H-dywyz?usp=sharing
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
책에 페치 조인 대상에는 별칭을 줄수 없다. 라고 나와서 궁금증이 생겼어여
책 381쪽에 보면 페치 조인 대상에는 별칭을 줄 수 없다라고 나오고, 대신 하이버네이트같은 몇몇 구현체는 지원해 준다고 나와있더라구요 "select distinct o from Order o" + " join fetch o.member m" + " join fetch o.delivery d" + " join fetch o.orderItems oi" + " join fetch oi.item i", 위와 같은 JPQL에서 o.orderItems 과 페치조인하고 oi로 별칭을 주었는데, 이 별칭을 활용하여 join fetch oi.item i 처럼 또 페치조인을 하는데... JPA에서 공식 스펙은 아니지만 하이버네이트가 잘 지원해주는 것 맞나요? 최종 질문은 저렇게 페치조인 대상에 별칭주고 거기서 또 페치조인해서... 잘 써도 되는지 궁금합니다. JPA의 공식스펙이 아닌것 같은데 문제없이 동작하는지.. (위 같은 경우는 당연 일대일이나 다대일에서만 쓸것입니다)
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
Junit5로 테스트 작성하기
메세지 검증방식으로 해보았습니다. Junit5로 시도하는분들에게 도움이 되길~ public class NotEnoughStockException extends RuntimeException{ @Override public String getMessage() { return "재고가 모자랍니다"; } } NotEnoughStockException thrown = assertThrows(NotEnoughStockException.class, () -> orderService.order(member.getId(), item.getId(), order)); assertEquals("재고가 모자랍니다", thrown.getMessage());
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
윈도우 명령어 관련 질문입니다.
윈도우는 h2.bat으로 접속을 했습니다. 2:08 부분에서 ll 와 ls - arlth 명령어를 통해 jpashop.mv.db가 생성되는 것을 확인할 때 윈도우 명령어로는 어떻게 진행해야 할까요? 보시는 것처럼 연결하게 되면 키 입력이 먹히지 않아 확인을 어떻게 해야할지... 윈도우 명령어랑 리눅스 명령어 비교를 해보려고 찾아봤는데 딱 맞는게 없는거 같아서 질문드립니다.
-
미해결실전! 스프링 데이터 JPA
현업에서 updatedAt 을 설계하나요?! (시스템/비즈니스 입장에서 )
학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 영한님 혹은 서포터즈 여러분 안녕하세요!강의를 열심히 수강하고 있었는데..프로젝트를 수행하던 도중 의문이 들어 하나 질문할게요! ㅎcreatedAt이나 updatedAt을 이용하면 운영상에 발생한 이슈들을 추적할 때 도움이 되는 것으로 알고 있어요!다만 updatedAt은 Entity 객체 혹은, DB의 row 의 일부분이 변경되면 바뀌는 것으로 알고 있거든요!이부분에서 질문 드립니다 ! 게시글 조회수가 올라가는 로직이 있다는 가정하에 이로 인하여 게시글 수정일시가 변경되면 안된다고 할 때 JPA/스프링에서 제공하는 변경감지 updatedAt을 사용할 수가 없거든요!이때는 별도로 시스템차원에서 변경한 systemUpdatedAt 과 비즈니스 의미상으로 변경한 businessUpdatedAt 등으로 나누는 것이 좋을까요??기타)createdAt은 시스템 입장에서 변경 / 비즈니스 입장에서 변경한 내역이 똑같은 것 같아용!
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
actuator/refresh 호출 시 오류 문의
안녕하세요. POSTMAN에서 POST방식으로 호출하는 경우, ConfigService쪽에 아래와 같은 오류가 발생합니다. 잘못 입력한 부분이 있는지 확인 부탁 드립니다. 1. user-service yml spring: application: name: user-service cloud: config: name: ecommerce config: import: optional:configserver:http://127.0.0.1:88882. config-service yml server: port: 8888spring: application: name: config-service cloud: config: server: git: uri: file://D:\\Projects\\intelliJ\\git-local-repo 3. 오류로그 org.springframework.cloud.config.server.environment.NoSuchLabelException: No such label: main at org.springframework.cloud.config.server.environment.JGitEnvironmentRepository.refresh(JGitEnvironmentRepository.java:314) ~[spring-cloud-config-server-3.1.3.jar:3.1.3] at org.springframework.cloud.config.server.environment.JGitEnvironmentRepository.getLocations(JGitEnvironmentRepository.java:262) ~[spring-cloud-config-server-3.1.3.jar:3.1.3] at org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentRepository.getLocations(MultipleJGitEnvironmentRepository.java:139) ~[spring-cloud-config-server-3.1.3.jar:3.1.3] at org.springframework.cloud.config.server.environment.AbstractScmEnvironmentRepository.findOne(AbstractScmEnvironmentRepository.java:55) ~[spring-cloud-config-server-3.1.3.jar:3.1.3] at org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentRepository.findOneFromCandidate(MultipleJGitEnvironmentRepository.java:188) ~[spring-cloud-config-server-3.1.3.jar:3.1.3] at org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentRepository.findOne(MultipleJGitEnvironmentRepository.java:173) ~[spring-cloud-config-server-3.1.3.jar:3.1.3] at org.springframework.cloud.config.server.environment.CompositeEnvironmentRepository.findOne(CompositeEnvironmentRepository.java:64) ~[spring-cloud-config-server-3.1.3.jar:3.1.3] at org.springframework.cloud.config.server.environment.EnvironmentEncryptorEnvironmentRepository.findOne(EnvironmentEncryptorEnvironmentRepository.java:61) ~[spring-cloud-config-server-3.1.3.jar:3.1.3] at org.springframework.cloud.config.server.environment.EnvironmentController.getEnvironment(EnvironmentController.java:134) ~[spring-cloud-config-server-3.1.3.jar:3.1.3] at org.springframework.cloud.config.server.environment.EnvironmentController.defaultLabelIncludeOrigin(EnvironmentController.java:116) ~[spring-cloud-config-server-3.1.3.jar:3.1.3] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na] at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282) ~[spring-core-5.3.21.jar:5.3.21] at org.springframework.cloud.context.scope.GenericScope$LockedScopedProxyFactoryBean.invoke(GenericScope.java:485) ~[spring-cloud-context-3.1.3.jar:3.1.3] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.21.jar:5.3.21] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.21.jar:5.3.21] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) ~[spring-aop-5.3.21.jar:5.3.21] at org.springframework.cloud.config.server.environment.EnvironmentController$$EnhancerBySpringCGLIB$$dc31df60.defaultLabelIncludeOrigin(<generated>) ~[spring-cloud-config-server-3.1.3.jar:3.1.3] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.21.jar:5.3.21] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.21.jar:5.3.21] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.21.jar:5.3.21] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.21.jar:5.3.21] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.21.jar:5.3.21] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.21.jar:5.3.21] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.21.jar:5.3.21] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.21.jar:5.3.21] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.21.jar:5.3.21] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.21.jar:5.3.21] at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.64.jar:4.0.FR] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.21.jar:5.3.21] at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.64.jar:4.0.FR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.64.jar:9.0.64] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.21.jar:5.3.21] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.21.jar:5.3.21] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.21.jar:5.3.21] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1787) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.64.jar:9.0.64] at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]Caused by: org.eclipse.jgit.api.errors.RefNotFoundException: Ref main cannot be resolved at org.eclipse.jgit.api.CheckoutCommand.call(CheckoutCommand.java:223) ~[org.eclipse.jgit-5.12.0.202106070339-r.jar:5.12.0.202106070339-r] at org.springframework.cloud.config.server.environment.JGitEnvironmentRepository.checkout(JGitEnvironmentRepository.java:468) ~[spring-cloud-config-server-3.1.3.jar:3.1.3] at org.springframework.cloud.config.server.environment.JGitEnvironmentRepository.refresh(JGitEnvironmentRepository.java:307) ~[spring-cloud-config-server-3.1.3.jar:3.1.3] ... 65 common frames omitted
-
미해결실전! 스프링 데이터 JPA
안녕하세요 영한님! 네이티브 쿼리 사용이 적절한 상황인지 궁금해서 질문드려요
우선 제가 하려는 동작은 "특정 브랜드의 카테고리별 상품의 최저가의 합" 을 구하는 쿼리를 작성해야했었고 결과물 쿼리는 " select sum(temp_mins.mins) as total from ( select min(price) mins from product where brand_num = ? group by category_num) as temp_mins" 위처럼 작성했습니다. 코드는 @Query(value = "select sum(temp_mins.mins) as total from (select min(price) mins from product where brand_num = ? group by category_num) as temp_mins", nativeQuery = true)Integer sumLowestPriceEachCategoryByBrand(Long brandNum); 입니다. queryDsl이나 JPQL에선 from절의 서브쿼리 기능을 제공하지 않는다고 파악되어서 고민끝에 네이티브 쿼리까지 왔는데요.현재 강의에서 네이티브 쿼리의 대표적인 단점으로 뽑아주신게 반환타입 부분으로 학습했는데 제 생각으로는 단순한 박싱 타입으로 반환하기 때문에 크게 문제가 없다고 생각됩니다. 혹시 위 코드가 네이티브 쿼리를 사용하는데 적절한 상황일까요?
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
영속성 전이 + 고아객체
안녕하세요 영한님! 영속성 전이 + 고아객체에 대해서 질문이 있습니다.! 강의 20분12초 쯤부터 설명하시는 내용을 들어보면 CascadeType.ALL + orphanRemovel = true를 설정하게 되면 부모 엔티티를 통해서 자식의 생명주기를 관리 할 수 있다고 말씀하셨는데 그러면 아래와 같은 코드가 있을때 public Parent findParent(Long id) { return em.find(Parent.class, id); } public void deleteParent(String name) { em.createQuery("delete from Parent p" + " where p.name = :name") .setParameter("name", name) .executeUpdate(); } @Transactional public void delete() { Parent parent = parentRepository.findParent(1L); parentRepository.deleteParent(parent.getName()); } 이런식으로 코드를 작성하면 자식도 함께 삭제가 안되는게 맞는 걸까요? 위와 같이 진행하면 무결성 참조 에러가 발생하여서 질문 남깁니다..! 😭 Referential integrity constraint violation 감사합니다. 장세웅 드림.
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
JPA repository, custom, impl 패키지 분리
안녕하세요. JPA Repositoy 관련해서 질문 드립니다. 관련 내용은 Data JPA 편이나 실전편도 연관 있지만 이번 강의와도 연관이 있어 최신 강의인 여기 게시판에 질문 올립니다.(영한님 모든 강의 수강중입니다) JPA를 사용해서 repository(JpaRepository) 를 구성할때 custom 및 impl 을 사용해서 repository를 구성하였습니다. 패키지 구성은 처음에는 모두 한 패키지에 넣어서 관리했었는데 비효율적이라 그 후에 아래와 같이 구성하였습니다. 기본 repository 패키지 : /repository custom repository 패키지: /repository/custom impl repository 패키지: /repository/custom/impl 이렇게 구성해서 잘 사용하고 있었는데, 최근에 연관된 여러 프로젝트를 하나로 묶는 멀티모듈 프로젝트로 구성을 변경하면서 각 모듈에서 공통으로 사용할 수 있는 '기본 repository 패키지'만 공통 모듈로 분리하고, custom, impl 레포지토리는 각각의 업무 모듈에 두고 싶어 구성 변경을 하다보니 JpaRepository를 상속한 repository는 같은 패키지 아래에 있지 않으면 Caused by: org.springframework.data.mapping.PropertyReferenceException: No property customMethod found for type Demo! 이런 형태로 에러가 발생합니다. 혹시 패키지를 완전히 분리해서 사용할 수 있는 방법이 있을까요? @EnableJpaRepositories는 사용해 봤는데 잘 안 되었습니다. 감사합니다.
-
미해결실전! 스프링 데이터 JPA
join 된 entity save시 cast 문제질문입니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요 우선 좋은강의 감사합니다. jpa수업을 들으며 개인적으로 응용해보며 공부하고 있습니다. 해당 질문은 개인적으로 응용하며 공부하던 중 발생한 문제에 대한 문의입니다. User Entity 1 : N Scrap Entity 구조에서 Scrap.java 의 addUser method를 구현하여 동시에 저장하려고 했습니다. 헌데 user Entity를 cast하지 못했다고 에러가 발생한것으로 보입니다. java.lang.ClassCastException: Cannot cast com.api.jpaTest.domain.entity.User to java.lang.String 해당 내용에 대한 힌트라도 알고싶습니다. token에서 user에 대한 정보는 정확히 가져왔고 해당 정보를 바탕으로 DB에서 User Entity를 정상적으로 조회하였습니다. scrap은 json 더미데이터가 있어서 데이터 역시 정상적으로 파싱하였습니다. 아래 코드 중 ScrapService.java 의 scrap() method 중 sr.save(userScrap)에서 오류가 발생합니다. User.java ( user Entity ) @Schema(description = "API 사용자 정보") @Builder @Table(name = "user") @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @ToString public class User extends BaseTimeEntity implements UserDetails { @Schema(description = "user table pk",defaultValue = "db generateValue") @Id @GeneratedValue @JsonIgnore @Column(name = "user_no") private Long id; @Schema(description = "user id") @Column(name = "user_id") private String userId; @Schema(description = "사용자 이름") @Column(name = "name") private String name; @Schema(description = "비밀번호") @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) @Column(name = "password") private String password; @Schema(description = "주민번호") @Column(name = "reg_no") private String regNo; @ElementCollection(fetch = FetchType.EAGER) @Builder.Default private List<String> roles = new ArrayList<>(); @Schema(description = "스크랩 정보 리스트") @JsonIgnore @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) @ToString.Exclude private List<Scrap> scraps = new ArrayList<>(); public void encodePassword(String password) { this.password = password; } public void encodeRegNo() throws EncodingException { this.regNo = AES256Util.encrypt(this.regNo); } public String decodeRegNo() throws EncodingException { return AES256Util.decrypt(this.regNo); } // security // @Override public Collection<? extends GrantedAuthority> getAuthorities() { return this.roles.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()); } @Override public String getUsername() { return this.userId; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } Scrap.java ( scrap Entity ) @Schema(description = "사용자 scrap 정보") @Builder @Table(name = "scrap") @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @ToString public class Scrap extends BaseEntity { @Schema(description = "scrap table pk") @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) @Id @GeneratedValue @Column(name = "scrap_no") private Long id; @Schema(description = "스크랩 성공 여부") @Column(name = "status") private String status; @Schema(description = "스크랩 에러 메세지") @Column(name = "errors") private String errors; @Schema(description = "스크랩 데이터 정보") @Embedded private ScrapPayData scrapPayData; @Schema(description = "스크랩 요청 일자") @Column(name = "worker_res_dt") private String workerResDt; @Schema(description = "스크랩 응답 일자") @Column(name = "worker_req_dt") private String workerReqDt; @Schema(description = "app version") @Column(name = "app_ver") private String appVer; @Schema(description = "user 정보") @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "user_no") // @ToString.Exclude private User user; public void setUser(User user) { this.user = user; } public void addUser(User user) { this.user = user; user.getScraps().add(this); } } ScrapService.java @Transactional public Result scrap() throws OtherException, EncodingException { User user = userService.getUser(); <-------- User Entity 정보 있음 ( 정상 조회 ) Scrap userScrap = getUserScrap(user); <----------- 더미 데이터를 기반으로 데이터 생성하여 데이터 있음 userScrap.addUser(user); sr.save(userScrap); <-----------저장 시 java.lang.ClassCastException: Cannot cast "User Entity path" to java.lang.String 에러 발생 return Result.builder() .statues(ApiStatus.SUCCESS) .data(userScrap.getId()) .errors("") .build(); } @Transactional Scrap getUserScrap(User user) throws EncodingException, OtherException { HashMap<String, String> jsonMap = new HashMap<>(); jsonMap.put("name",user.getName()); jsonMap.put("regNo",user.decodeRegNo()); JSONObject requestJson = new JSONObject(jsonMap); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> entity = new HttpEntity<String>(requestJson.toString(),headers); SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setConnectTimeout(20000); requestFactory.setReadTimeout(20000); RestTemplate restTemplate = new RestTemplate(requestFactory); ResponseEntity<String> response = restTemplate.postForEntity( ScrapConstant.URL.getMsg(), entity, String.class ); return jsonToEntity(response.getBody()); } Scrap jsonToEntity(String json) throws OtherException { try { ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false); ScrapDto scrapDto = mapper.readValue(json, ScrapDto.class); JSONObject data = new JSONObject(mapper.writeValueAsString(scrapDto.getData())); JSONObject jsonList = new JSONObject(mapper.writeValueAsString(scrapDto.getData())).getJSONObject(ScrapConstant.LIST.getMsg()); JSONArray scrap002 = jsonList.getJSONArray(ScrapConstant.SCRAP_NUM2.getMsg()); JSONArray scrap001 = jsonList.getJSONArray(ScrapConstant.SCRAP_NUM1.getMsg()); return Scrap.builder() .status(scrapDto.getStatus()) .errors(scrapDto.getErrors().toString()) .appVer((String) data.get("appVer")) .workerReqDt((String) data.get("workerReqDt")) .workerResDt((String) data.get("workerResDt")) .scrapPayData( new ScrapPayData((String) scrap002.getJSONObject(0).get("총사용금액"), (String) scrap001.getJSONObject(0).get("총지급액")) ) .build(); } catch (Exception e) { throw new OtherException(e); } } Exception Message java.lang.ClassCastException: Cannot cast com.api.jpaTest.domain.entity.User to java.lang.String at java.base/java.lang.Class.cast(Class.java:3605) ~[na:na] at com.api.jpaTest.domain.entity.Scrap_Accessor_kqrtpb.setProperty(Unknown Source) ~[classes/:na] at org.springframework.data.mapping.model.InstantiationAwarePropertyAccessor.setProperty(InstantiationAwarePropertyAccessor.java:104) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.mapping.model.SimplePersistentPropertyPathAccessor.setProperty(SimplePersistentPropertyPathAccessor.java:127) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.mapping.model.SimplePersistentPropertyPathAccessor.setProperty(SimplePersistentPropertyPathAccessor.java:171) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingMetadataAuditableBeanWrapper.lambda$setProperty$0(MappingAuditableBeanWrapperFactory.java:259) ~[spring-data-commons-2.6.2.jar:2.6.2] at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na] at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingMetadataAuditableBeanWrapper.setProperty(MappingAuditableBeanWrapperFactory.java:259) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingMetadataAuditableBeanWrapper.setCreatedBy(MappingAuditableBeanWrapperFactory.java:204) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.auditing.AuditingHandlerSupport.touchAuditor(AuditingHandlerSupport.java:169) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.auditing.AuditingHandlerSupport.lambda$touch$0(AuditingHandlerSupport.java:136) ~[spring-data-commons-2.6.2.jar:2.6.2] at java.base/java.util.Optional.map(Optional.java:265) ~[na:na] at org.springframework.data.auditing.AuditingHandlerSupport.touch(AuditingHandlerSupport.java:134) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.auditing.AuditingHandlerSupport.markCreated(AuditingHandlerSupport.java:114) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.auditing.AuditingHandler.markCreated(AuditingHandler.java:92) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.jpa.domain.support.AuditingEntityListener.touchForCreate(AuditingEntityListener.java:92) ~[spring-data-jpa-2.6.2.jar:2.6.2] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.hibernate.jpa.event.internal.ListenerCallback.performCallback(ListenerCallback.java:55) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.jpa.event.internal.CallbackRegistryImpl.callback(CallbackRegistryImpl.java:97) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.jpa.event.internal.CallbackRegistryImpl.preCreate(CallbackRegistryImpl.java:57) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:108) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:760) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:746) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362) ~[spring-orm-5.3.16.jar:5.3.16] at com.sun.proxy.$Proxy142.persist(Unknown Source) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311) ~[spring-orm-5.3.16.jar:5.3.16] at com.sun.proxy.$Proxy142.persist(Unknown Source) ~[na:na] at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:637) ~[spring-data-jpa-2.6.2.jar:2.6.2] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:529) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:639) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:163) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174) ~[spring-data-jpa-2.6.2.jar:2.6.2] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.16.jar:5.3.16] at com.sun.proxy.$Proxy159.save(Unknown Source) ~[na:na] at com.api.jpaTest.service.ScrapService.scrap(ScrapService.java:50) ~[classes/:na] at com.api.jpaTest.service.ScrapService$$FastClassBySpringCGLIB$$46dc0c0.invoke(<generated>) ~[classes/:na] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.16.jar:5.3.16] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698) ~[spring-aop-5.3.16.jar:5.3.16] at com.api.jpaTest.service.ScrapService$$EnhancerBySpringCGLIB$$b9877c5.scrap(<generated>) ~[classes/:na] at com.api.jpaTest.controller.ScrapController.scrap(ScrapController.java:33) ~[classes/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.16.jar:5.3.16] at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) ~[tomcat-embed-core-9.0.58.jar:4.0.FR] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.16.jar:5.3.16] at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.58.jar:4.0.FR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:109) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at com.api.jpaTest.config.jwt.JwtAuthenticationFilter.doFilter(JwtAuthenticationFilter.java:33) ~[classes/:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267) ~[spring-web-5.3.16.jar:5.3.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
BeanCreationException 질문드립니다.
Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: jpabook.jpashop.domain.item.Item.categories[jpabook.jpashop.domain.Category] 이런 에러가 발생합니다. 코드 첨부합니다. 해당 부분을 지우면 문제없이 돌아가요.. package jpabook.jpashop.domain;import jpabook.jpashop.domain.item.Item;import lombok.Getter;import lombok.Setter;import javax.persistence.*;import java.util.ArrayList;import java.util.List;@Embeddable@Getter@Setterpublic class Category { @Id @GeneratedValue @Column(name = "category_id") private Long id; private String name; @ManyToMany @JoinTable(name = "category_item", joinColumns = @JoinColumn(name = "category_id"), inverseJoinColumns = @JoinColumn(name = "item_id")) private List<Item> items = new ArrayList<>(); @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") private Category parent; @OneToMany(mappedBy = "parent") private List<Category> child = new ArrayList<>(); public void addChildCategory(Category child) { this.child.add(child); child.setParent(this); } protected Category(){}} package jpabook.jpashop.domain.item;import jpabook.jpashop.domain.Category;import lombok.Getter;import lombok.Setter;import javax.persistence.*;import java.util.ArrayList;import java.util.List;@Entity@Inheritance(strategy = InheritanceType.SINGLE_TABLE)@DiscriminatorColumn(name = "dtype")@Getter @Setterpublic abstract class Item { @Id @GeneratedValue @Column(name = "item_id") private Long id; private String name; private int price; private int stockQuantity; @ManyToMany(mappedBy = "items") private List<Category> categories = new ArrayList<Category>();}
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
주문할 때 상품 여러개 선택하는 기능 추가
안녕하세요, 이 프로그램을 좀 더 발전시켜보고 싶은데요 주문할 때 상품을 여러개 선택하도록 만들고싶은데, 이렇게 하려면 상품과 주문 수량을 골랐을 때 다시 화면에 추가로 선택 칸이 만들어져야 할 것 같습니다. 이 기능을 혹시 스프링과 타임리프 만으로 구현할 수 있나요, 아니면 자바스크립트를 공부해서 만들어야 할까요? 대략적인 가이드라도 조언 부탁드립니다. 감사합니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
insert문에 null이 아닌 default값이 들어옵니다.
안녕하세요. jpa예제에 phonenumber라는 객체 추가해줘서 실습중입니다. 그런데 김영한 강사님의 출력문이랑은 다르게 Hibernate: insert into member (id, name, phonenumber) values (default, ?, ?) 와 같이 null이 아닌 default 값이 들어옵니다. 이유를 찾아보니 아래 테이블 생성문에 문제가 있는것으로 보입니다. create table member( id bigint generated by default as identity, name varchar(255), phoneNumber varchar(255), primary key (id));여기서 by default 부분때문인것 같은데 이 ddl파일은phoneNumber빼고는 김영한 강사님과 똑같이 만들었다고 생각하는데저렇게 출력문이 다르게 나오는 이유가 뭔지 알 수 있을까요??감사합니다.