묻고 답해요
131만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
JPA flush 와 commit 의 차이가 뭔지 이해가 안갑니다.
제목 그대로입니다. 블로그 찾아보니 flush 는 영속성 컨텍스트의 내용을 DB에 동기화 시키는 것, 이라고 하고 커밋은 트랜잭션을 종료하는데 쓴다고하더라구요!. @Transactional public void likePost(final Member currentMember,final Long postId){ try{ postLockRepository.getLock(postId.toString()); final Post post = findPost(postId); //post 의 작성자와 좋아요를 누르려는 사람의 ID 값이 같을 떄 예외 if (post.getMember().getId() == currentMember.getId()) { throw new NotFoundException(ErrorCode.MESSAGE_NOT_FOUND); } //이미 눌러져 있을 때 deleteLikePost 수행, 없다면 saveLikePost 수행 likePostRepository.findByMemberIdAndPostId(currentMember.getId(), post.getId()) .ifPresentOrElse(likePost -> { deleteLikePost(likePost, post);}, () -> { saveLikePost(currentMember, post); System.out.println("pp"); }); } finally{ postLockRepository.releaseLock(postId.toString()); } } private void saveLikePost(final Member member,final Post post){ LikePost lp= LikePost.builder() .post(post) .member(member) .build(); likePostRepository.save(lp); System.out.println("gg"); post.increaseLikeCount(); postRepository.saveAndFlush(post); System.out.println("kk"); }이 코드에서 saveLikepost 를 실행하면 post 에 대한 좋아요 가 하나 증가합니다. 그리고 saveAndFlush를 통하면 update 쿼리가 바로 나가더라구요!. 이 같이 쿼리를 발생시키고 flush 를 했으니 영속성 컨텍스트에 있는 post 의 like_count 는 1이 증가되어야 합니다. 또한 likePostRepository.save() 도 역시 insert 쿼리가 나가고요!질문 요약: 저희가 알고있는 개념대로라면 영속성 컨텍스트에 있는 @Transactional 안에 있는 Save를 한 대상(LikePost) 와 @Transactional 안에 있는 SaveFlush 대상 역시 FLUSH를 통해 DB와 동기화 시킨다고 생각했습니다. (DB에 동기화시켰으니까 insert 하는 대상은 DB에 생겨야 하고, update 한 거는 update 가 제대로 반영이 되어야 한다고 생각했습니다) 그런데 위 과정에서 디버깅을 해보니(하이버네이트로 쿼리가 날라가는 것은 확인이 되었습니다) 실제 DB에 데이터가 들어가지 않고 @Transactional 이 끝나야 DB에 반영이 되더라고요!! 제가 동기화에 대해 이해를 잘 못하고 있는 걸까요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
No Persistence provider for EntityManager named hello
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]실전예제1을 따라하다가이런 에러가 나는데 이유를 모르겠어요,, 어떻게 하면 해결할 수 있을까요? 그리고 h2DB 연결도 안되어서 찾아봤더니url을 jdbc:h2:~/jpashop 이렇게 하면 된다고 해서 이렇게 해서 db접속을 했고,persistence.xml에도 url을 위와 동일하게 설정해두었습니다.프로젝트 압축파일 구글드라이브에 올려놓았습니다!도움 부탁드립니다.https://drive.google.com/file/d/1S5ytUHGS0cpr7LSvlFF5E8qyiTwjlOs-/view?usp=sharing
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
DB 자동 생성 기능이 동작하지 않습니다 도와주세요ㅠㅠㅠ
예제로 올려주신 ex1-hello-jpa가 Maven 기반으로 되어있어서 Gradle 기반의 예제로 학습해보기 위해 최대한 비슷한 예제 파일을 만들었습니다. 하지만 이 예제에서는 애플리케이션 실행 시 DB 자동 생성 관련 부분이 아예 동작하지 않습니다. (로그도 뜨지 않고, 실제로 쿼리도 수행되지 않습니다.)프로젝트를 암만 뒤져봐도 JDBC 연결 정보도 다 전달했고, @Entity까지 다 했는데 왜 동작을 안 하는지 정말 모르겠습니다.https://drive.google.com/file/d/1epXZLqjRw8ssBAv6zKaVM7T7IpQ24hPW/view?usp=sharing프로젝트 파일 링크입니다. 고수분들 도와주시면 정말 감사하겠습니다 ㅠㅠㅠ
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
Whitelabel Error Page 라고 나옵니다.. 구글링해 보면서 찾아보았는데 어떻게 해결하죠?(해결)
2024-04-11 12:48:27.471 INFO 24733 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2024-04-11 12:48:27.471 INFO 24733 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2024-04-11 12:48:27.472 INFO 24733 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 msh2-console로 들어갔을때의 에러 코드이고이렇게 사이트 에러가 나오고#spring: # config: # activate: # on-profile: local # datasource: # url: "jdbc:h2:mem:library;MODE=MYSQL;NON_KEYWORDS=USER" # username : "jo" # password : "" # driver-class-name : org.h2.Driver #jpa: # hibernate: # ddl_auto : create # properties : # hibernate: # format_sql: true # show_sql : ture # dialect: org.hibernate.dialect.H2Dialect # #h2: # console: # enabled : true # path: /h2-console spring: config: activate: on-profile: local datasource: url: "jdbc:h2:mem:library;MODE=MYSQL;NON_KEYWORDS=USER" username: "sa" password: "" driver-class-name: org.h2.Driver jpa: hibernate: ddl-auto: create properties: hibernate: format_sql: true show_sql: true dialect: org.hibernate.dialect.H2Dialect open-in-view: false h2: console: enabled: true path: /h2-console --- #spring: # datasource: ## //Spring boot가 어떠한 dababase를 가리키게 할 것인가 # url: "jdbc: mysql://localhost/library" ## jdbc -> java로 만든 DB-connector ## : mysql -> 종류는 mysql ## //localhost 사용할 주소 ## /사용할 DB # username: "root" # password : "1234" # driver-class-name: com.mysql.cj.jdbc.Driver ## DB에 접근할 때 사용할 프로그램을 의미 spring: config: active: on-profile: dev datasource: url: "jdbc:mysql://localhost/library" username: "root" password: "" driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: none properties: hibernate: show_sql: true format_sql: true dialect : org.hibernate.dialect.MySQL8Dialect open-in-view: false작성한 yml코드 입니다...2024-04-11 18:52:49.259 INFO 27511 --- [ main] c.g.libraryapp.LibraryAppApplication : Starting LibraryAppApplication using Java 18.0.2 on Jun0.local with PID 27511 (/Users/jojun-yeong/Desktop/강의 자료/1월25/Java_Spring_Library_Application/library-app/out/production/classes started by jojun-yeong in /Users/jojun-yeong/Desktop/강의 자료/1월25/Java_Spring_Library_Application/library-app) 2024-04-11 18:52:49.262 INFO 27511 --- [ main] c.g.libraryapp.LibraryAppApplication : The following 1 profile is active: "local" 2024-04-11 18:52:49.899 INFO 27511 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. 2024-04-11 18:52:49.959 INFO 27511 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 51 ms. Found 3 JPA repository interfaces. 2024-04-11 18:52:50.529 INFO 27511 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-04-11 18:52:50.539 INFO 27511 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2024-04-11 18:52:50.540 INFO 27511 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.69] 2024-04-11 18:52:50.632 INFO 27511 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2024-04-11 18:52:50.632 INFO 27511 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1317 ms 2024-04-11 18:52:50.798 INFO 27511 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2024-04-11 18:52:51.112 INFO 27511 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2024-04-11 18:52:51.164 INFO 27511 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] 2024-04-11 18:52:51.233 INFO 27511 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.14.Final 2024-04-11 18:52:51.460 INFO 27511 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final} 2024-04-11 18:52:51.577 INFO 27511 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect 2024-04-11 18:52:52.113 INFO 27511 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] 2024-04-11 18:52:52.121 INFO 27511 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' 2024-04-11 18:52:52.547 WARN 27511 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning 2024-04-11 18:52:52.793 INFO 27511 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2024-04-11 18:52:52.799 INFO 27511 --- [ main] c.g.libraryapp.LibraryAppApplication : Started LibraryAppApplication in 4.005 seconds (JVM running for 4.452)
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
runtime 에러 납니다.
서버 모두 기동시킨후에 했는데 runtime 오류가 납니다. 왜그러는걸까요,,? <zookeeper-server 기동><Kafka server 기동><Kafka Connect 기동>
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
mysql centos7서버 연결문제
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요 선생님^^ 강의 잘보고 있습니다. 항상 수고하십니다.h2 DB 말고 mysql centos7서버로 연결하려고 합니다. 서버에 연결까지하고 테이블까지는 생겼는데 데이터를 입력하고 저장을 누르면ava.sql.SQLException: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation '=' at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-java-8.0.29.jar:8.0.29] at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.29.jar:8.0.29] at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) ~[mysql-connector-java-8.0.29.jar:8.0.29] at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:972) ~[mysql-connector-java-8.0.29.jar:8.0.29] at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) ~[HikariCP-3.4.5.jar:na] at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) ~[HikariCP-3.4.5.jar:na] at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.loader.Loader.getResultSet(Loader.java:2304) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2057) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2019) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.loader.Loader.doQuery(Loader.java:948) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.loader.Loader.doList(Loader.java:2850) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.loader.Loader.doList(Loader.java:2832) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2664) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.loader.Loader.list(Loader.java:2659) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:506) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1414) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1625) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1593) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.query.Query.getResultList(Query.java:165) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at jpabook.jpashop.repository.MemberRepository.findByName(MemberRepository.java:32) ~[main/:na] 이러한 에러가 발생합니다. 뭐가 문제 일까요 ㅜㅜㅜ
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
8000번 포트 404에러 & 유레카 등록된 인스턴스
유레카에 등록된 게이트웨이 서비스의 인스턴스 아이디도 따로 설정을 해줘야하는지 문의드립니다. 자꾸 저렇게 뜨네요.. 포트 8000번으로 요청시에 404 에러가 뜹니다. 어떤 부분을 수정해야할까요? <사용자 조회시> <로그인시>
-
미해결실전! 스프링 데이터 JPA
JPA join 관련 질문
안녕하세요 JPA 학습중 join 관련하여 질문 드립니다. public class Score{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long scoreId; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "game_id") private Game game; }Score라는 클래스가 있고, Game 엔티티와 ManyToOne 연관관계가 있을 때 public interface ScoreRepository extends JpaRepository<Score,Long>{ @Query("select s from Score s join s.game g left join s.member m left join m.profileImg p " + "where g.gameId=:gameId and (p.type = 'PROFILE' OR p IS NULL) order by s.totalScore desc") Slice<Score> findByGameId(@Param("gameId") Long gameId, Pageable pageable); } Game별 Score를 가져올 경우 해당 게임에 등록된 스코어가 없는 경우 결과가 반환되지 않아서 Game 엔티티의 게임명이나 게임타입 같은 게임정보를 가져올수가 없습니다. right join을 사용해보려 했는데 리턴값이 Slice<Score>라서 그런지 형변환 오류가 발생하는 것 같구요..이럴경우에는 Game 엔티티에서 @OneToMany 연관관계를 사용해서 결과를 가져와야하나요?? 그럴 경우 페이징은 어떻게 해결해야하는지 잘모르겠습니다..
-
미해결스프링 프레임워크는 내 손에 [스프2탄]
안녕하세요. spring boot 에서 하는중인데 질문 드립니다.!
spring boot 로 프로젝트 만들고 하는중이라서 부트에서 테스트 하고 있는데요. 구글링 해서 테스트 세팅하고 modelAndView 까지 했는데 view 값은 가져오는데 model 값이 안가져와지네요.... @MockBean 으로 Service 를 bean 등록 시키고 Service 에서 getList 할때 뭔가 잘안되는거 같은데 혹시 어떤게 잘못됬는지 확인 가능하신가요 ?? ControllerService testController testConstroller test 결과
-
미해결코드로 배우는 React with 스프링부트 API서버
노란색 경고글을 없애고 싶어요..
프론트 부분에서 ESLint 때문에 계속 에러를 겪고 있는데요,,해결했다 싶으면 신기하게도 다음번 컴퓨터를 키면 또 에러가 생겨있고 그러는데요,빨간색 에러는 없앴는데 노란색 경고글도 없애고 싶습니다.아래 노란색 경고글들도 없앨수 있는 방법이 있을까요...에러때문에 이것저것 시도하다가 뭔가 버전이 안맞는 걸까요...
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
처음 설치시 버전
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]동영상은 2점대에 설치인거같은데 현재는 아래처럼 나옵니다. 어느기준에 맞춰야 하나요?임시로 아래 사진처럼 내리긴 했는데 JpashopApplication 동작화살표 버튼이 없어서요
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
AMQP 안돼요
userservice나 apigateway 서버 올리면 native로 저장된 파일 불러와야하는데 불러오지를 못해요.무엇을 확인해봐야 할까요,,,?config - application.yml / bootstrap.ymlUserService - bootstrap.yml
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
merge과 remove, cascade에 대한 질문
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]코드 먼저 보여드리겠습니다public void execute(){ EntityManager em = entityManagerFactory.createEntityManager(); EntityTransaction tx = em.getTransaction(); try { tx.begin(); Writing writing = new Writing("A"); Image image1 = new Image("order1"); Image image2 = new Image("order2"); image1.setWriting(writing); image2.setWriting(writing); writing.getImageList().add(image1); writing.getImageList().add(image2); em.persist(writing); em.flush(); em.clear(); Writing findWriting = em.find(Writing.class, writing.getId()); List<Image> imageList = findWriting.getImageList(); for (Image image : imageList) { em.remove(image); // 실행? 실행안됨? } System.out.println("=============persist start =============="); em.persist(image1); System.out.println("=============persist stop =============="); tx.commit(); }catch (Exception e){ e.printStackTrace(); tx.rollback(); }finally { em.close(); } }public class Writing { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "writing_id") private Long id; @Column(name = "writing_name") private String name; @OneToMany(mappedBy = "writing", cascade = CascadeType.ALL) private List<Image> imageList = new ArrayList<>();public class Image { @Id @GeneratedValue @Column(name = "order_id") private Long id; private String OrderName; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "writing_id") private Writing writing; public Image(String orderName) { OrderName = orderName; } }제가 여기서 궁금한건, for (Image image : imageList) { em.remove(image); // 실행? 실행안됨? } 이 부분부터 인데,Cascade.ALL로 설정해서, Writing과 image가 객체 관 연관관계가 설정되어 있기때문에 cascade 입장에서는 persist 하려하고, em.remove 입장에서는 삭제하려하기에 충돌이 일어나서 결국 삭제되지 않는 건 이해 했습니다.이때 em.clear로 영속성 컨텍스트에 있는 writing와 image1, image2가 현재 detached된 상태가 맞다고라고 가정하고 제 질문은 다음과 같습니다.1. em.remove(image) 자체의 코드가 "실행"은 되어서 detached된 image1, image2를 removed, 즉 영속성 컨텍스트에서 아에 제거 된 상태로 만든다라고 이해한게 맞는지?2.그리고 detached된 엔티티이든, persist 되어있는 엔티티이든 둘 다 remove 하면 결과값은 "영속성 컨텍스트에서 제거"라는 것으로 똑같은지?3. 만약 removed가 되어있다고 하면, em.persist가 다음과 같은 오류와 함께 실행 안되는 이유... 다음 에러에는 detached된 엔티티는 persist 할 수 없다는데 그렇다면 실제로 remove 된게 아닌지? 그렇다기엔 em.merge(image1)를 하면 새로운 객체를 생성해서 DB 에 저장하는데 ㅠ =============persist start ==============jakarta.persistence.EntityExistsException: detached entity passed to persist: com.example.jpatest.entity.Image...
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
안녕하세요. 강의를 보다가 궁금한 점이 있습니다.
Microservcie간 통신 강의를 보다가 궁금하게 있어서 질문드립니다.user-service에서 order-service를 요청할때 인증은 필요가 없는건가요?order-service를 요청할때 따로 헤더에 토큰을 담지 않고 요청을 하고 있어서요.order-service를 IP로 지정하지 않고 유레카에 서비스 이름으로 지정해서 요청할때도 gateway를 통해서 요청이 들어 가는것인가요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
JPQL과 SQL 차이가 잘 이해가 안갑니다.
JPQL은 엔티티 객체를 대상으로 쿼리한다고 하고 SQL은 DB 테이블을 대상으로 쿼리한다고 하시는데이 말이 잘 이해가 안 갑니다. Jpql을 통해 결국 SQL을 생성하는것도 이해했고 Jpql이 특정 DB에 종속적이지 않다는 말도 이해했습니다. 다만 검색 쿼리로서 Jpql의 용도를 하기 위해서는 Jpql도 결국 DB 테이블을 대상으로 쿼리를 하는게 아닌가요?엔티티 객체를 대상으로 쿼리를 한다는 말이 잘 이해가 안갑니다. 엔티티 객체라는 말 자체가 혼동이 됩니다.저는 평소 엔티티라는 말을 RDB 관점에서 다른것들과 구별을 가지는 DB에서의 클래스 정도로 이해하고 있습니다. 여기 JPA강의에서 엔티티는 @Entity 어노테이션을 통해 JPA에서 관리하고 RDB의 테이블과 1대1로 매칭되는 단위 정도로 이해하고 있습니다. 거기다가 객체라는 용어도 평소 프로그래밍에서 쓰던대로 클래스를 구현한 실체정도로 생각한다면, 여기 JPA강의에서 엔티티 객체라는 말은 한 번이라도 영속화를 시켜준 실체라고 이해해야 하나요? 정확한 정의가 궁금합니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
1차 캐시와 트랜잭션 격리 수준 관련 질문
안녕하세요. 자바 ORM 표준 JPA 프로그래밍 책으로 학습 중에 "1차 캐시를 통해 Repeatable Read 수준의 트랜잭션 격리 수준을 제공한다"는 내용을 보고 궁금증이 생겨 질문 남깁니다. 격리 수준이 Read-Committed와 Repeatable Read인 경우, 언두 로그를 이용한 MVCC로 한 트랜잭션 내에서 반복적인 읽기를 보장한다고 알고 있습니다.하지만 이 둘을 성능 관점에서 봤을 때 언두 로그에 있는 Row를 삭제하는 범위가 달라져 상대적으로 Repetalbe Read가 성능이 더 안 좋다고도 알고 있습니다.결과적으로 1차 캐시를 통해 애플리케이션 레벨에서 Read Committed를 보장해 주는데, 굳이 MySQL 서버에서는 불필요하게 언두 로그에 더 많은 Row를 저장하면서까지 Repetable Read를 설정할 필요가 없다고 생각이 됐습니다. 따라서 MySQL 8.0 기준으로 JPA를 사용하면, 트랜잭션 격리 수준을 Repetable Read로 설정하지 않아도 되나요?
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
mvn spring-boot:run 실행불가 (꼭 해결해주세요)
찾아보니 비슷한 질문이 있었던 거 같은데 현재 실습환경과 100% 일치하지 않아 도움을 구합니다. 실행환경은 다음과 같습니다 인텔리제이 : Build #IU-241.14494.240, built on March 28, 2024JDK : 17스프링부트 : 3.2.4 아시다 시피 최신 인텔리제이에서는 실습환경으로 제시되는 2.X 버전의 스프링부트 지원이 되지 않습니다. POM.XML로 강제로 버전을 내리거나 JDK 버전을 내리는 경우 서비스 기동이 제대로 되지 않습니다. 아마 스프링부트 3 버전에서는 JDK 특정 버전 이상을 강제하는 느낌입니다. 현재 pom.xml 설정은 다음과 같습니다. <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>user-serivce</artifactId> <version>0.0.1-SNAPSHOT</version> <name>user-serivce</name> <description>user-serivce</description> <properties> <java.version>17</java.version> <spring-cloud.version>2023.0.1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project> 명렁어 실행 시 에러는 다음과 같이 발생합니다. [ERROR] Unknown lifecycle phase ".run.jvmArguments=-Dserver.port=9003". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: pre-clean, clean, post-clean, validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-site, site, post-site, site-deploy. -> [Help 1] 동일한 명렁어를 윈도우즈 cmd에서 실행하면 다음과 같습니다. [WARNING] Error injecting: org.springframework.boot.maven.RunMojojava.lang.TypeNotPresentException: Type org.springframework.boot.maven.RunMojo not present at org.eclipse.sisu.space.URLClassSpace.loadClass (URLClassSpace.java:147)(중략)Caused by: java.lang.UnsupportedClassVersionError: org/springframework/boot/maven/RunMojo has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0 본 문제 때문에 강의 진행이 안되고 있습니다.꼭 해결해 주셨으면 합니다.
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
jwt 인증401 뜹니다.
@Component @Slf4j public class AuthorizationHeaderFilter extends AbstractGatewayFilterFactory<AuthorizationHeaderFilter.Config> { Environment env; public AuthorizationHeaderFilter(Environment env) { super(Config.class); this.env = env; } public static class Config { // } @Override public GatewayFilter apply(Config config) { // ServerWebExchange 파라미터는 필터가 동작하는 동안 현재 요청 및 응답에 대한 정보를 제공한다. // 비동기 서버 Netty 에서는 동기 서버(ex:tomcat)와 다르게 request/response 객체를 선언할 때 Server~ 를 사용한다. GatewayFilter filter = (exchange, chain) -> { ServerHttpRequest request = exchange.getRequest(); // 요청 헤더에 "Authorization" 헤더가 포함되어 있는지 확인한다. if (!request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) { // "Authorization" 헤더가 없는 경우, UNAUTHORIZED(401) 상태로 에러 응답을 반환. return onError(exchange, "No Authorization header", HttpStatus.UNAUTHORIZED); } // "Authorization" 헤더에서 JWT 토큰을 추출. String authorizationHeader = request.getHeaders().get(HttpHeaders.AUTHORIZATION).get(0); // "Bearer " 문자열을 삭제하고 토큰만 추출 String jwt = authorizationHeader.replace("Bearer ", ""); log.info("authorizationHeader : " + authorizationHeader); log.info("jwt : " + jwt ); // 추출한 JWT 토큰의 유효성을 확인. if (!isJwtValid(jwt)) { return onError(exchange, "JWT Token is not valid", HttpStatus.UNAUTHORIZED); } // JWT 토큰이 유효한 경우, 다음 필터로 요청을 전달. return chain.filter(exchange); }; return filter; } private boolean isJwtValid(String jwt) { // 반환값으로 사용할 boolean 변수를 초기값 true로 설정 boolean returnValue = true; // JWT의 'subject'를 저장할 변수 초기화 String subject = null; try { // 환경 변수에서 토큰의 비밀 키 가져오기 String secretKey = env.getProperty("token.secret"); log.info("secretkey : " + secretKey); // JWT 파서를 생성하고 토큰의 비밀 키 설정 JwtParser jwtParser = (JwtParser) Jwts.parser().setSigningKey(secretKey); // JWT 파서를 사용하여 토큰을 파싱하고 Claims 객체를 반환 Claims claims = jwtParser.parseClaimsJws(jwt).getBody(); // 토큰에서 'subject' 정보 추출 subject = claims.getSubject(); log.info("subject:" + subject); } catch (Exception e) { // 예외가 발생하면 JWT가 유효하지 않다고 판단하고 반환값을 false로 변경 returnValue = false; } // 'subject' 값이 비어있으면 JWT가 유효하지 않다고 판단하고 반환값을 false로 변경 if (subject == null || subject.isEmpty()) { returnValue = false; } // 최종적으로 JWT의 유효성 여부를 나타내는 반환값을 반환 return returnValue; } // Mono, Flux -> Spring WebFlux (기존의 SpringMVC 방식이 아니기때문에 Servlet 을 사용하지 않음) private Mono<Void> onError(ServerWebExchange exchange, String err, HttpStatus httpStatus) { ServerHttpResponse response = exchange.getResponse(); response.setStatusCode(httpStatus); log.error(err); return response.setComplete(); } }authorizationHeader : Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6Iltjb20uZXhhbXBsZS5qd3Rqd3QuZmlsdGVyLkN1c3RvbVVzZXJEZXRhaWxzJDFANjIxMDI1MGNdIiwiaWF0IjoxNzEyNjUxODYzLCJleHAiOjE3MTI2NTE4OTl9.oH-cw5zNVM43LIEj173W0zof5PcbhIa6CiTq1lEHRWs jwt : eyJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6Iltjb20uZXhhbXBsZS5qd3Rqd3QuZmlsdGVyLkN1c3RvbVVzZXJEZXRhaWxzJDFANjIxMDI1MGNdIiwiaWF0IjoxNzEyNjUxODYzLCJleHAiOjE3MTI2NTE4OTl9.oH-cw5zNVM43LIEj173W0zof5PcbhIa6CiTq1lEHRWs secretkey : user_token JWT Token is not valid이렇게 뜨는데 뭐가 문제일까요??
-
미해결Practical Testing: 실용적인 테스트 가이드
환경별 DB 분리 질문있습니다.
안녕하세요.application.yml에서 local, test로 환경을 나누어서 h2 db를 통해 테스트 코드를 만들어보고있습니다.나중에 운영 서버나 릴리즈 서버같은곳에 빌드, 배포할때도 테스트를 진행해야 할텐데 DB 주소를 어떻게 설정하는게 좋을까요? 각각 실제로 사용할 DB의 주소를 적어놓을텐데 빌드하면서 테스트를 진행하면 해당 DB의 테이블과 데이터를 건드리게 될거란 생각이 들어서요..테스트용 resources로 yml을 따로 작성해서 해야할까요?
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
N + 1 쿼리 횟수
안녕하세요 강의 너무 잘 듣고 있습니다."간단한 주문 조회 V2: 엔티티를 DTO로 변환" 강의를 듣던 중 궁금한 점이 생겨 질문 드립니다.Order 엔티티를 SimpleOrderDto로 변환하는 과정에서 아래 조건으로 인해 샘플 데이터 2개 기준 총 5(1 + 2 + 2)번의 쿼리가 날아간다고 이해했습니다.order -> member 지연 로딩 조회 N번order -> delivery 지연 로딩 조회 N번근데 저는 order -> delivery 쿼리 이후에 order를 찾는 쿼리가 한번 더 날아가는 것처럼 보입니다. 총 7번의 쿼리가 발생하는 것 같은데 무엇 때문인지 설명해주실 수 있을까요?코드와 콘솔 로그는 아래 첨부했습니다. 감사합니다.// Order 엔티티 @Id @GeneratedValue @Column(name = "order_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) private List<OrderItem> orderItems = new ArrayList<>(); @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "delivery_id") private Delivery delivery; private LocalDateTime orderDate; @Enumerated(EnumType.STRING) private OrderStatus status; // 주문상태 // Delivery 엔티티 @Id @GeneratedValue @Column(name = "delivery_id") private Long id; @JsonIgnore @OneToOne(mappedBy = "delivery", fetch = FetchType.LAZY) private Order order; @Embedded private Address address; @Enumerated(EnumType.STRING) private DeliveryStatus status; // READY, COMP // OrderSimpleApiController @GetMapping("/api/v2/simple-orders") public List<SimpleOrderDTO> ordersV2() { List<Order> orders = orderRepository.findAll(new OrderSearch()); return orders.stream() .map(SimpleOrderDTO::new) .toList(); } @Data static class SimpleOrderDTO { private Long orderId; private String name; private LocalDateTime orderDate; private OrderStatus orderStatus; private Address address; public SimpleOrderDTO(Order order) { this.orderId = order.getId(); this.name = order.getMember().getName(); // Lazy 초기화 this.orderDate = order.getOrderDate(); this.orderStatus = order.getStatus(); this.address = order.getDelivery().getAddress(); // Lazy 초기화 } }2024-04-09T13:27:53.982+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 join member m1_0 on m1_0.member_id=o1_0.member_id 2024-04-09T13:27:53.984+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636873984|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 join member m1_0 on m1_0.member_id=o1_0.member_id|select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 join member m1_0 on m1_0.member_id=o1_0.member_id 2024-04-09T13:27:54.005+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select m1_0.member_id, m1_0.city, m1_0.street, m1_0.zipcode, m1_0.name from member m1_0 where m1_0.member_id=? 2024-04-09T13:27:54.007+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636874007|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=?|select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=1 2024-04-09T13:27:54.012+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select d1_0.delivery_id, d1_0.city, d1_0.street, d1_0.zipcode, d1_0.status from delivery d1_0 where d1_0.delivery_id=? 2024-04-09T13:27:54.013+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636874013|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=?|select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=1 2024-04-09T13:27:54.016+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 where o1_0.delivery_id=? 2024-04-09T13:27:54.016+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636874016|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=?|select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=1 2024-04-09T13:27:54.018+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select m1_0.member_id, m1_0.city, m1_0.street, m1_0.zipcode, m1_0.name from member m1_0 where m1_0.member_id=? 2024-04-09T13:27:54.019+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636874019|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=?|select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=2 2024-04-09T13:27:54.020+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select d1_0.delivery_id, d1_0.city, d1_0.street, d1_0.zipcode, d1_0.status from delivery d1_0 where d1_0.delivery_id=? 2024-04-09T13:27:54.020+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636874020|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=?|select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=2 2024-04-09T13:27:54.021+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 where o1_0.delivery_id=? 2024-04-09T13:27:54.021+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636874021|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=?|select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=2