RolehierarchyImpl 에 String 타입 프로퍼티에 A > B\n 이런 타입으로 지정만 해주면 될 것 같아서 Role 엔티티 자체에 RoleGrade 라는 ENUM 타입을 지정해줘서 알파벳 순으로 가져와서 그걸 for-loop 돌리면서 문자열만 만들면 될거 같아서 해봤는데 실시간으로 적용이 되더라구요. @Override public void reloadRoleHierarchy () { StringBuilder sb = new StringBuilder (); List < Role > allRoles = roleRepository . findAllWithRoleGrade (); for ( int i = 0 ; i < allRoles . size (); i ++) { try { allRoles . get ( i + 1 ); /* 검증 코드 */ sb . append ( allRoles . get ( i ). getRoleName ()); sb . append ( " > " ); sb . append ( allRoles . get ( i + 1 ). getRoleName ()); sb . append ( " \n " ); } catch ( Exception e ) { break ; } } this . roleHierarchy . setHierarchy ( sb . toString ()); } ResourcesController 에서 자원 등록, 삭제 하고나서 reload 메소드를 호출했듯이 이 메소드를 Role 등록, 삭제 뒤에 등록해주니 잘 되네요. 혹시 실무에서는 이런식으로 쓰는것보다 엔티티를 따로 만들어서 관리하는것을 선호하나요? RoleHierarchy 엔티티 안에 자기 자신을 ManyToOne 으로 조인하니 너무 어려워서 이렇게 해보긴 했는데, 실무에서는 엔티티 방식으로 관리하는걸 선호하는지 궁금해서 질문드립니다. 혹시 몰라 git 링크 첨부해봅니다. 한번 봐주시면 감사하겠습니다. review4 브랜치입니다. https://github.com/twosom/SpringSecurity-ProjectReview.git *추가적으로 이제 계층 구조 Role을 구성했으면 Resources 랑 Role 은 굳이 N : N 관계로 구성하지 않아도(테이블 상에서는 1 : N , N : 1) 되는건가요? 기존에는 하나의 Reosurces 에 여러개의 Role 이 있을 수 있고 Role 하나가 여러 Resources 에 포함될 수 있기에 N : N 관계로 만들었지만, 계층 구조가 적용되면 외래키가 Resources 테이블에만 존재해도 (N : 1) 될 것 같아서요. 항상 좋은 강의 감사드립니다.
안녕하세요. 파이썬 머신러닝 완벽가이드, 캐글 Advanced 머신러닝 실전 박치기 강의와 책( 파이썬 머신러닝 완벽가이드) 을 통해 머신러닝을 공부하고 있는 직장인 입니다. 수업내용과는 직접적으로 관련은 없지만 궁금한게 있어서 문의드립니다. sklearn으로 만들어진 lightGBM, RandomForest 모델을 save해서 load하는데 pickle , joblib 등을 활용이 되는건 알겠는데 그렇게 저장된 model을 java에서 호출하여 사용하는 방법이 혹시 있는지 알고싶습니다. tensorflow는 model save시 hdf5 형식으로 저장 후 java에서 load해서 사용한다고들 하는데 sklearn으로 만들어진 모델은 혹시 어떤 방법이 있을까요? * 강의와 직접적인 연관이 없는 질문인거 같아 메일을 통해 문의를 드려볼까 하였으나, 메일주소를 알수가 없어서 이렇게 질문게시판에 남깁니다.
안녕하세요. 학습편 수강 후에 취업편 수강 예정인 수강생입니다. 비슷한 내용이었을 것으로 예상되는 커리큘럼 질문이 있었지만 문의사항에 기재된 주소가 유효기간 만료된 주소였던 지라 제 개인적인 질문들을 포함해서 질문드려봅니다. 1. 저는 몇 년간 경험을 쌓고 서비스 창업이 목표인 사람입니다. 학습편을 수강하면서 현재 제게 친밀한 ios 개발을 목표로 하자고 다짐하였는데요. 유튜브를 보다보니 앱 개발이 아닌 PWA를 통해서도 서비스를 구현할 수 있다, 꼭 앱 개발이 답이 아니다. 라는 이야기를 들어서요. 해당 부분에 대해서 어떻게 생각하시는지 궁금합니다. (제가 초보자다보니 질문이 구체적이지 못한 점 양해 부탁드려요...) 2. 앱 개발이 아닌 웹 개발로 준비하게 된다면 국비지원 학원을 다닐 생각입니다. JS을 시작으로 풀스택을 노려보고 싶은데 국비지원 학원 내 커리큘럼 중에서는 js로 풀스택을 가르치는 곳이 없는 듯합니다. 이 상황에서, 비용은 고려하지 않고, 국비지원학원 JAVA 풀스택 강좌가 최선일까요...? 3. 2번에서 제가 말씀드렸던 강좌의 커리큘럼을 아래에 첨부합니다. 커리큘럼이 비교적 잘 구성된 편인지 확인해주시면 대단히 감사하겠습니다. 이런 질문들을 남겨도 괜찮은지 모르겠습니다. 주변에 아는 지인이 없고, 커뮤니티에 질문을 올려도 반응이 없어서 밑져야 본전이라는 심정으로 질문 남깁니다. 이 글을 읽으시는 모든 분들, 오늘도 좋은 하루 보내시길 바라며, 항상 건승하시길 바랍니다.
안녕하세요 강사님! 활용편 1,2편에 이어서 이번 실전편도 듣고 있습니다. 활용편 2편에서 DTO로 조회하시는 걸 알려주셨는데요. 언듯 보기에는 DTO로 조회하는 것과 프로젝션으로 조회하는것이 비슷해 보이는데, 제가 지금 이해하기로는 - DTO의 경우 엔티티의 모든 필드를 조회해서 DTO에 넣어준다음에 반환 - 프로젝션의 경우 프로젝션에 선언한 필드만 조회해서 반환 하는 차이만 있는 걸까요? 아니면 제가 잘못알고있거나 이해하지 못한 부분이 있는지 궁금합니다 ! 만약 단순하게 하나의 엔티티를 조회한다 할 경우, DTO와 프로젝션 어느 쪽을 더 선호하시는 지 궁금합니다 ! 감사합니다 !
안녕하세요 강사님. 저번에 친절하게 올려주신 답변을 보고 따라하는 중에 또 질문을 올리네요!! Keras-yolo를 데스크탑 gpu로 train해서 만든 .h5파일을 노트북 cpu로 inference 과정 중 문제가 생겼습니다. 모델 로드는 제대로 되었는데, Yolo의 detect_image()를 사용하여 inference 중 아레와 같은 에러가 발생하였습니다! 혹시 cpu에서 keras-YOLO는 사용이 불가능한 것일까요? -------------- 모델 학습 25회 학습 + validation 2회 진행 중 한번 끊겨서 중간 저장된 model_stage_1.h5로 5회 학습 + 5회 validation 진행한 결과입니다. train_yolo(pretrained_path, annotation_path,classes_path, anchors_path, log_dir,trained_model_name, b_size, epochs_cnt) pretrained_path: C:/JupyterNotebook/ClothClassified/model_data/cloth_stage_1.h5 Create Tiny YOLOv3 model with 6 anchors and 14 classes. Load weights C:/JupyterNotebook/ClothClassified/model_data/cloth_stage_1.h5. Freeze the first 42 layers of total 44 layers. Train on 28938 samples, val on 3215 samples, with batch size 2. Epoch 1/5 14469/14469 [==============================] - 2273s 157ms/step - loss: 17.7330 - val_loss: nan WARNING:tensorflow:From C:\Users\min96\anaconda3\envs\tf115\lib\site-packages\keras\callbacks\tensorboard_v1.py:343: The name tf.Summary is deprecated. Please use tf.compat.v1.Summary instead. Epoch 2/5 14469/14469 [==============================] - 2078s 144ms/step - loss: 17.6376 - val_loss: nan Epoch 3/5 14469/14469 [==============================] - 2094s 145ms/step - loss: 17.5342 - val_loss: nan Epoch 4/5 14469/14469 [==============================] - 2049s 142ms/step - loss: 17.6445 - val_loss: nan Epoch 5/5 14469/14469 [==============================] - 2042s 141ms/step - loss: 17.6296 - val_loss: nan Unfreeze all of the layers. Train on 28938 samples, val on 3215 samples, with batch size 2. Epoch 6/10 14469/14469 [==============================] - 2111s 146ms/step - loss: 14.0190 - val_loss: 5.6780 Epoch 7/10 14469/14469 [==============================] - 2111s 146ms/step - loss: 11.0151 - val_loss: 4.3427 Epoch 8/10 14469/14469 [==============================] - 2114s 146ms/step - loss: 9.7026 - val_loss: 7.6887 Epoch 9/10 14469/14469 [==============================] - 2115s 146ms/step - loss: 9.0433 - val_loss: 2.4560 Epoch 10/10 14469/14469 [==============================] - 2105s 146ms/step - loss: 8.5110 - val_loss: 7.9146 ------------- 모델 로드 cloth_tiny_yolo = YOLO(model_path=pretrained_path, anchors_path=anchors_path, classes_path=classes_path) C:/JupyterNotebook/model_data/cloth_final.h5 model, anchors, and classes loaded. ----------------------- train detected_img = yolo.detect_image(img) plt.imshow(detected_img) (192, 192, 3) --------------------------------------------------------------------------- UnimplementedError Traceback (most recent call last) ~\anaconda3\envs\t115c\lib\site-packages\tensorflow_core\python\client\session.py in _do_call (self, fn, *args) 1364 try : -> 1365 return fn ( * args ) 1366 except errors . OpError as e : ~\anaconda3\envs\t115c\lib\site-packages\tensorflow_core\python\client\session.py in _run_fn (feed_dict, fetch_list, target_list, options, run_metadata) 1349 return self._call_tf_sessionrun(options, feed_dict, fetch_list, -> 1350 target_list, run_metadata) 1351 ~\anaconda3\envs\t115c\lib\site-packages\tensorflow_core\python\client\session.py in _call_tf_sessionrun (self, options, feed_dict, fetch_list, target_list, run_metadata) 1442 fetch_list , target_list , -> 1443 run_metadata) 1444 UnimplementedError : The Conv2D op currently does not support grouped convolutions on the CPU. A grouped convolution was attempted to be run because the input depth of 512 does not match the filter input depth of 1 [[{{node conv2d_49/convolution}}]] During handling of the above exception, another exception occurred: UnimplementedError Traceback (most recent call last) <ipython-input-23-b6fbc29987b5> in <module> 1 # with tf.device('/cpu:0'): ----> 2 detected_img = yolo . detect_image ( img ) 3 plt . imshow ( detected_img ) C:\JupyterNotebook\model_data\keras-yolo3\yolo.py in detect_image (self, image) 122 self . yolo_model . input : image_data , 123 self . input_image_shape : [ image . size [ 1 ] , image . size [ 0 ] ] , --> 124 K . learning_phase ( ) : 0 125 }) 126 ~\anaconda3\envs\t115c\lib\site-packages\tensorflow_core\python\client\session.py in run (self, fetches, feed_dict, options, run_metadata) 954 try : 955 result = self._run(None, fetches, feed_dict, options_ptr, --> 956 run_metadata_ptr) 957 if run_metadata : 958 proto_data = tf_session . TF_GetBuffer ( run_metadata_ptr ) ~\anaconda3\envs\t115c\lib\site-packages\tensorflow_core\python\client\session.py in _run (self, handle, fetches, feed_dict, options, run_metadata) 1178 if final_fetches or final_targets or ( handle and feed_dict_tensor ) : 1179 results = self._do_run(handle, final_targets, final_fetches, -> 1180 feed_dict_tensor, options, run_metadata) 1181 else : 1182 results = [ ] ~\anaconda3\envs\t115c\lib\site-packages\tensorflow_core\python\client\session.py in _do_run (self, handle, target_list, fetch_list, feed_dict, options, run_metadata) 1357 if handle is None : 1358 return self._do_call(_run_fn, feeds, fetches, targets, options, -> 1359 run_metadata) 1360 else : 1361 return self . _do_call ( _prun_fn , handle , feeds , fetches ) ~\anaconda3\envs\t115c\lib\site-packages\tensorflow_core\python\client\session.py in _do_call (self, fn, *args) 1382 '\nsession_config.graph_options.rewrite_options.' 1383 'disable_meta_optimizer = True') -> 1384 raise type ( e ) ( node_def , op , message ) 1385 1386 def _extend_graph ( self ) : UnimplementedError : The Conv2D op currently does not support grouped convolutions on the CPU. A grouped convolution was attempted to be run because the input depth of 512 does not match the filter input depth of 1 [[node conv2d_49/convolution (defined at C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\tensorflow_core\python\framework\ops.py:1748) ]] Original stack trace for 'conv2d_49/convolution': File "C:\Users\min96\anaconda3\envs\t115c\lib\runpy.py", line 193, in _run_module_as_main "__main__", mod_spec) File "C:\Users\min96\anaconda3\envs\t115c\lib\runpy.py", line 85, in _run_code exec(code, run_globals) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\ipykernel_launcher.py", line 16, in <module> app.launch_new_instance() File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\traitlets\config\application.py", line 664, in launch_instance app.start() File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\ipykernel\kernelapp.py", line 612, in start self.io_loop.start() File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\tornado\platform\asyncio.py", line 199, in start self.asyncio_loop.run_forever() File "C:\Users\min96\anaconda3\envs\t115c\lib\asyncio\base_events.py", line 442, in run_forever self._run_once() File "C:\Users\min96\anaconda3\envs\t115c\lib\asyncio\base_events.py", line 1462, in _run_once handle._run() File "C:\Users\min96\anaconda3\envs\t115c\lib\asyncio\events.py", line 145, in _run self._callback(*self._args) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\tornado\ioloop.py", line 688, in <lambda> lambda f: self._run_callback(functools.partial(callback, future)) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\tornado\ioloop.py", line 741, in _run_callback ret = callback() File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\tornado\gen.py", line 814, in inner self.ctx_run(self.run) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\tornado\gen.py", line 162, in _fake_ctx_run return f(*args, **kw) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\tornado\gen.py", line 775, in run yielded = self.gen.send(value) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\ipykernel\kernelbase.py", line 365, in process_one yield gen.maybe_future(dispatch(*args)) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\tornado\gen.py", line 234, in wrapper yielded = ctx_run(next, result) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\tornado\gen.py", line 162, in _fake_ctx_run return f(*args, **kw) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\ipykernel\kernelbase.py", line 268, in dispatch_shell yield gen.maybe_future(handler(stream, idents, msg)) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\tornado\gen.py", line 234, in wrapper yielded = ctx_run(next, result) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\tornado\gen.py", line 162, in _fake_ctx_run return f(*args, **kw) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\ipykernel\kernelbase.py", line 545, in execute_request user_expressions, allow_stdin, File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\tornado\gen.py", line 234, in wrapper yielded = ctx_run(next, result) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\tornado\gen.py", line 162, in _fake_ctx_run return f(*args, **kw) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\ipykernel\ipkernel.py", line 306, in do_execute res = shell.run_cell(code, store_history=store_history, silent=silent) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\ipykernel\zmqshell.py", line 536, in run_cell return super(ZMQInteractiveShell, self).run_cell(*args, **kwargs) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\IPython\core\interactiveshell.py", line 2867, in run_cell raw_cell, store_history, silent, shell_futures) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-packages\IPython\core\interactiveshell.py", line 2895, in _run_cell return runner(coro) File "C:\Users\min96\anaconda3\envs\t115c\lib\site-pa
강사님, 안녕하세요. Item 클래스에서 id의 변수에 @Column(name = "ITEM_ID") private Long id; 위와 같은 식으로 네임 속성으로 ITEM_ID를 주어 데이터베이스의 컬럼과 id 변수의 이름을 맞추신 것 같습니다. 그런데 위에 코드를 private Long item_id; 와 같이 바로 데이터베이스와 맞추어서 persist로 영속성을 주어 DB에 입력하는 방법은 어떤지 궁금합니다. 답변 꼭 부탁드리겠습니다. 감사합니다.
안녕하세요! 이전 질문에서 영한님 답변을 받고 원인을 해결하여 다른 경우 또한 테스트해보고 있는데 SQL Error: 23503 에러가 발생했고, 구글링 결과 참조 키 제약조건 위배될 때 발생하는 에러라 하는데 아래 상황에서 왜 이 에러가 뜨는지 모르겠어서 질문을 남깁니다. Parent, child 끼리 연관관계 매핑 후, cascadetype.ALL, orphanRemoval=false로 설정한 후, parent를 삭제할 때 발생한 에러입니다. 먼저 Parent, Child, Main 클래스 코드를 보여드리겠습니다! @Entity public class Parent { @Id @GeneratedValue private Long id; private String name; @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL) private List<Child> children=new ArrayList<>(); public void addChild(Child child){ children.add(child); child.setParent(this); } // getter, setter 생략했습니다 } @Entity public class Child { @Id @GeneratedValue private Long id; private String name; @ManyToOne(fetch = FetchType.LAZY) private Parent parent; // getter, setter 메소드 생략했습니다 } Parent 클래스, Child 클래스는 위와 같이 작성했으며, cascadetype.ALL로 설정해놓았고, 고아 객체 제거는 설정하지 않았습니다. 메인 코드는 아래와 같습니다. public class JpaMain { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); EntityManager em=emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); try{ Parent parent=new Parent(); parent.setName("kth990303"); Child child1=new Child(); child1.setName("kthbaby1"); Child child2=new Child(); child2.setName("kthbaby2"); parent.addChild(child1); parent.addChild(child2); em.persist(parent); em.flush(); em.clear(); Parent findParent = em.find(Parent.class, parent.getId()); System.out.println("===================1"); findParent.getChildren().remove(0); em.remove(findParent); System.out.println("===================3"); tx.commit(); } catch(Exception e){ e.printStackTrace(); tx.rollback(); } finally{ em.close(); } emf.close(); } } 역시 orphanRemoval=true가 아니었기 때문에 findParent.getChildren().remove( 0 ) ; 코드에서, 아무 일이 일어나지 않고 지연로딩으로 인한 child select 쿼리만 날라가는건 예상대로였는데, 문제는 그 아래 em.remove(findParent); 였습니다. 이미 em.find로 영속성 컨텍스트에 정보가 있어 parent를 지울 때 에러가 발생하지 않은 상태로 parent와 children 모두 지워질 줄 알았는데 아래 사진과 같은 에러가 발생했습니다. 사실 parent를 지울 때 그냥 findParent.getChildren().remove(0); 을 작성하지 않고 em.remove(findParent);만 하면 parent가 지워짐과 동시에 children도 모두 잘 지워지는 성공적인 결과가 보이긴 합니다만,,, 위와 같이 코드를 짠 후 실행했더니 SQL ERROR 23503이 뜨는 이유가 궁금하여 질문드립니다. 금쪽같은 주말에 질문을 좀 많이 하는 듯하네요 ㅠㅠ 죄송합니다. 그리고 감사합니다 :) ===================1 Hibernate: select children0_.parent_id as parent_i3_2_0_, children0_.id as id1_2_0_, children0_.id as id1_2_1_, children0_.name as name2_2_1_, children0_.parent_id as parent_i3_2_1_ from Child children0_ where children0_.parent_id=? ===================3 Hibernate: /* delete hellojpa.Child */ delete from Child where id=? Hibernate: /* delete hellojpa.Parent */ delete from Parent where id=? 5월 15, 2021 8:20:45 오후 org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions WARN: SQL Error: 23503, SQLState: 23503 5월 15, 2021 8:20:45 오후 org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions ERROR: Referential integrity constraint violation: "FKLH67J1N7X7GT59U0PBKWQH6O6: PUBLIC.CHILD FOREIGN KEY(PARENT_ID) REFERENCES PUBLIC.PARENT(ID) (1)"; SQL statement: /* delete hellojpa.Parent */ delete from Parent where id=? [23503-199] 5월 15, 2021 8:20:45 오후 org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release INFO: HHH000010: On release of batch it still contained JDBC statements javax.persistence.RollbackException: Error while committing the transaction at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:81) at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104) at hellojpa.JpaMain.main(JpaMain.java:43) Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154) at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181) at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:65) ... 2 more Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:59) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200) at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:45) at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3551) at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3810) at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:124) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478) at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475) at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40) at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102) at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1352) at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:443) at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3202) at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2370) at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281) at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101) ... 1 more Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation: "FKLH67J1N7X7GT59U0PBKWQH6O6: PUBLIC.CHILD FOREIGN KEY(PARENT_ID) REFERENCES PUBLIC.PARENT(ID) (1)"; SQL statement: /* delete hellojpa.Parent */ delete from Parent where id=? [23503-200] at org.h2.message.DbException.getJdbcSQLException(DbException.java:459) at org.h2.message.DbException.getJdbcSQLException(DbException.java:429) at org.h2.message.DbException.get(DbException.java:205) at org.h2.message.DbException.get(DbException.java:181) at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:373) at org.h2.constraint.ConstraintReferential.checkRowRefTable(ConstraintReferential.java:390) at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:265) at org.h2.table.Table.fireConstraints(Table.java:1057) at org.h2.table.Table.fireAfterRow(Table.java:1075) at org.h2.command.dml.Delete.update(Delete.java:153) at org.h2.command.CommandContainer.update(CommandContainer.java:198) at org.h2.command.Command.executeUpdate(Command.java:251) at org.h2.server.TcpServerThread.process(TcpServerThread.java:406) at org.h2.server.TcpServerThread.run(TcpServerThread.java:183) at java.lang.Thread.run(Unknown Source) at org.h2.message.DbException.getJdbcSQLException(DbException.java:457) at org.h2.engine.SessionRemote.done(SessionRemote.java:607) at org.h2.command.CommandRemote.executeUpdate(CommandRemote.java:237) at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:200) at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:154) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197) ... 21 more 5월 15, 2021 8:20:45 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PoolState stop INFO: HHH10001008: Cleaning up connection pool [jdbc:h2:tcp://localhost/~/test] Process finished with exit code 0
안녕하세요 강사님. 강의 복습 중에 질문이 생겨서 문의 드립니다 JPA 에서 DTO 직접조회를 하는데 (일대다 조회) 일반적으로 엔티티를 DTO 로 변환해서 조회하는 방법보다 더 불편하고 유지보수할때 복잡해 보이는데, 실제 운영에서도 DTO를 직접조회해서 사용을 많이 할까요 ??
저는 cmd를 사용하지 않고 구글에서 cmmder을 설치하여 사용합니다. 제일 먼저 spring 디렉토리로 이동합니다. cd 디렉토리 그 후 ls -al을 입력해 보면 gradlew.bat 이라는 이름의 bat파일이 보이실 거에요. 복사하여 gradlew.bat build를 해줍니다. 위와 같이 Build Successful이라 뜨면 성공한거구요. ls -al을 해보면 build 폴더가 보이실 거고 cd build를 해주신 다음에 cd libs 해주고 해당 디렉토리에서 java -jar hello-spring-0.0.1-SNAPSHOT.jar 이렇게 해주니 성공적으로 실행이 돼네요. 어찌보면 영상에 나와있는 내용 그대로 글로 적은것 뿐이지만 누군가에게 도움이 돼셨길 바라며
주니어 개발자로 현재 SI업체에서 근무하고 있는데, 개발시 Mybatis를 사용합니다. 강의를 듣고 간단하게 JPA를 적용해서 샘플 프로젝트정도를 만들어 보았는데 개인적으로는 매우 마음에 들어서 프로젝트에도 한번 써보고 싶어서 사수에게 건의 하였으나 JPA는 간단한 CRUD에는 좋은데 실제 프로젝트에서는 통계등을 조회해야하는데 매우 많은 조인들이 들어가고 sql 쿼리만 수백줄이 되는데, 이런걸 JPA가 대체하기 어렵다. 라는 답변을 받아서 문의 드립니다. 근데 생각해보면 좀 이상한게 해외에서는 JPA가 더 많이 사용된다는데 해외에는 차트같은게 없나..? 싶은 생각이 들더라구요. 그래서 JPA가 mybatis를 완벽히 대체가 가능한건지, 아니면 둘을 병행해서 써야 하는건지 궁금합니다.
안녕하세요 김영한님! 제가 드리고싶은 질문은 두가지입니다. 예를 들어 게시글에는 이미지를 넣을 수 있으며 게시글과 이미지는 OneToMany관계로 이루어져있습니다. 그리고 Board(게시글) 엔티티에는 @OneToMany(mappedBy = "board", Cascade.ALL, orphonRemoval = true, fetch = LAZY) List<BoardImage> images = new ArrayList<>(); 로 설정했습니다. 질문1. 예를 들어 이미지가 [image1, image2, image3](타입은 이미지객체타입) 에서 [image2, image3, image4] 로 update 할 경우에는 1. delete all & insert all 2. 코드로 기존과 하나하나 비교하면서 delete1 & insert 4 인가? 주로 현업에서는 어떻게 사용하는지 궁금합니다. 질문2. List<BoardImage> images = [image1, image2, image3] 을 갖고 있습니다. 여기서 update 메소드를 사용하여 this.images = List.of(image1, image3, image4)로 덮을경우에는 JPA에서 전부 delete하는지 궁금합니다. 감사합니다
안녕하세요, 영한쌤. Category에서 private Category parent에 있지도 않은 parent_id를 @JoinColumn 기준으로 잡아주는 것이 너무 이상했는데 create table할 때 parent_id 필드가 만들어지더라구요. 명시적으로 만든 적이 없는 parent_id를 가지고 @JoinColumn에 이걸로 연결하라고 사용해도 오류가 나지 않을 뿐더러 심지어 parent_id가 생성되는 이유가 궁금합니다.
처음에 Authentication객체를 SecurityContext에 담아서 보관한다는것 까지능 이해했습니다. 그럼 SecurityContext가 저장되는 곳이 1. ThreadLocal 2. HttpSession 3. SecurityContextHolder 총 3개의 공간에 저장되는 건가요? 그리고 이 공간은 각각 독립된 공간인건가요? 아니면 ThreadLocal안에 SecurityContextHolder가 포함되고 HttpSession은 따로 저장되는 구조인건가요? 궁금합니다.
김영한 강사님 안녕하세요. 좋은 강의 항상 잘 보고있습니다! ㅎㅎ 다름이 아니라 강의를 쭉 듣던 중 궁금증이 생겼습니다. MemberRepository에서 em은 @PersistenceContext를 붙였는데 ItemRepository에서는 @PersistenceContext를 붙이지 않고 그냥 final 처리만 되어있습니다. 제가 보기엔 둘다 같은 역할을 하는 em인것 같은데 소스코드에서는 왜 다르게 구현하신건지 궁금합니다!
마지막 참고에서는 트래픽이 많은 API는 OSIV를 끄고, 많은 트래픽이 없어 커넥션을 유지해도 되는 상태인 ADMIN같은 경우는 OSIV를 켜두는 것이 좋다고 하셨습니다!!! 여기서 궁금한 점이 spring.jpa.open-in-view는 글로벌 설정인데 한 애플리케이션에서는 화면 의존적인 서비스가 있을 수도 있고 아닐 수도 있다고 생각합니다. (여러 서비스가 있을 수도 있다고 생각합니다.) 그렇다면 개별적으로 osiv를 설정하는 방법이 있는건가요? (항상 좋은 강의 감사합니다.)
안녕하세요 선생님! 혼자 복습하다가 문득 호기심이 생겨, 상품 서비스의 테스트를 진행해보다 . @SpringBootTest class ItemServiceTest { @Autowired private ItemService itemService ; @Test void 상품 _ 등록 () { Book book = new Book() ; book.setName( "jpa" ) ; book.setPrice( 10000 ) ; Long itemId = itemService .saveItem(book) ; Assertions. assertThat (book).isEqualTo( itemService .findOne(itemId)) ; } } 이렇게 되면 테스트가 실패하는데 그 이유가 객체 타입이 달라서 그런건가요? 테스트 코드의 객체는 Book이고 service 계층에서의 반환형은 Item이라 생각하여 Repository 계층과 Service 계층의 반환형을 모두 Book으로 해도 테스트가 실패합니다. 혹시 이유를 알 수 있을까요?
안녕하세요. 영한님 오랜만에 인사드립니다. MySQL Dialect 중 하나인 group_concat을 추가하여 사용해야 하는 상황이라.. 다음과 같이 Custom을 만들고 프로퍼티로 해당 CustomDialect까지 등록되어 정상 동작하는 상황입니다. public class CustomMySQL57Dialect extends MySQL57Dialect { public CustomMySQL57Dialect() { registerFunction("GROUP_CONCAT", new StandardSQLFunction("group_concat", StandardBasicTypes.STRING)); } } 문제는, Native Query로는 `GROUP_CONCAT(DISTINCT xxx)` 처럼 사용이 가능하나, QueryDSL을 이용한 상황에서 해당 DISTINCT가 동작하지 않습니다.. 위와 같은 상황을 겪어보셨을 지 않을까 싶어 여쭤봅니다! QueryDSL 코드 중 일부는 다음과 같습니다. select(Projections.constructor(PaymentFilterConditionDTO.class, transaction.merchantMemberNo, Expressions.stringTemplate("group_concat(DISTINCT {0})", new CaseBuilder().when(transaction.userType.eq(UserType.LINE_PAY)) .then(transaction.transactionType.stringValue() .concat(transaction.paymentMethod.stringValue())) .otherwise(transaction.transactionType.stringValue().concat(transaction.paymentMethod.stringValue()) .concat(SUFFIX_AFFILIATE))))) from(...) where(...) 위의 QueryDSL 코드에서 DISTINCT가 제외되면 예외없이 동작하구요. DISTINCT가 있을 때는 다음과 같이 예외가 발생합니다. - unexpected token : group_concat - unexpected token : DISTINCT 항상 도움주셔서 다시 한 번 감사합니다.
안녕하세요 영한님 드디어 야생형 코스가 끝났습니다! 스프링 MVC도 이제 곧 구매 대기 중입니다ㅎㅎ 다름이 아니라 TDD 관련 질문입니다. 질문을 어디다 해야될지 모르겠어서 여기 다 질문합니다.. 1. 보통 Spring에서 각 계층별로 TDD를 진행하나요? 예를 들어, entity -> repository -> service -> controller 순으로 수업을 진행하셨는데 실무에서는 entity 개발 후에 entity 로직에 대한 tdd, respository tdd, service tdd, controller tdd 이런 식으로 다하나요? 2. 각 계층별로 단위 테스트와 통합 테스트를 전부 다 하는 건가요? 현재 프로젝트를 진행하는 데 계층별로 단위 테스트와 통합 테스트를 다 해야되는 건지 궁금했는데 구글링해도 자료가 잘 없네요ㅠㅠ
안녕하세요 영한님 벌크성 수정 쿼리 강의해주실 때 em.flush() em.clear() 를해야한다(영속성 컨텍스트에 있는 캐시정보들을 DB에 반영하기 위해)고 말씀해주셨는데 만약 어떤 user들의 age가 20이 넘는 사람의 인원수가 5명이라고 가정하고 이들의 나이를 1씩 올렸다고 가정했을때 캐시에는 반영이 안되고 바로 DB에만 반영이 되는데 이때 제가 궁금했던것은 em.flush를 하면 1치캐시에 있는것을 db에 반영시키는것(더티체킹을 포함하여) 이라고 생각해서 이 경우에는 1차캐시가 반영되면 안되는것 아닌가요? 캐시 DB -> 벌크성수정쿼리-> 캐시 DB -> em.flush() -> 캐시 DB 40 40 40 41 40 40