묻고 답해요
138만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
FakeRepository 만들 때 Join 테이블하는 경우 질문드립니다.
서비스 테스트 시 Repository 상속해서 FakeRepository를 생성자 주입을 통해 진행한다는 내용에 대해서는 이해하고 실습해 보았습니다.그런데 만약 Repository 메서드 중 JPA의 on 절을 이용한 join을 사용해 데이터를 가져오는 경우 FakeRepository의 내부 구현이 궁금합니다내부에 Id와 List를 통해 해당 엔티티에 대한 정보를 저장할 수 있지만, Join을 하는 경우 외부 테이블의 정보가 필요하기 때문에 이를 Fake하고 싶을 때는 어떻게 해결할 수 있는지 알려주시면 감사하겠습니다.
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
Mybatis만 사용하는 경우의 Data Class 구조에 조언 구합니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예 - 부분적인 관련이긴 합니다ㅜ)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]JPA를 사용하는 경우 Entity와 request/response(DTO)를 구분하는 부분은 충분히 공감하였습니다.그러면 혹시 Mybatis만을 활용하여 SQL로 바로 접근하는 프로젝트의 경우도 JPA와 같이 DB 계층(Entity/Repository)과 그 외 계층(DTO - Controller/Service)을 구분하여 Data Class를 설계하는 것이 필요할까요?현재 프로젝트는 Mybatis만을 사용하고 있으며 각 요청과 응답에 대해서는 request와 response DTO를 각각 생성하여 사용하고 있는 상황입니다.강의를 듣다보니 여기에 추가적으로 DB 계층으로 접근할 때의 Data Class를 추가하여 접근하는 것이 필요하지 않을까 해서 질문 드리게 되었습니다. 강의 내용과 조금 거리가 있을 수 있으나 궁금함이 생겨 간단한 의견이라도 부탁 드립니다.
-
해결됨Practical Testing: 실용적인 테스트 가이드
Beverage 인터페이스
테스트의 질문과는 좀 벗어나는 질문입니다만.. 궁금해서 여쭤보게 되었습니다!간단한 프로젝트를 구성하는 과정에서 Beverage라는 인터페이스를 만들어 추상화를 진행하고 해당 인터페이스는 get의 행위만 가지고 있었습니다.그리고 추가된 라떼와 아메리카노 둘 다 같은 속성이지만 구현을 통해서 두 개의 구성 클래스를 만들어 예제를 진행하였는데요.이에 다음과 같은 의문점이 생겼습니다.인터페이스가 get이라는 행위만 가져도 사용해도 괜찮은지. 지금과 같은 상황에서는 확장에서의 의미로 추상 클래스가 더 괜찮을 것 같은데 사용하지 않은 이유가 있으신지 궁금합니다ㅎㅎ좋은 강의 제공해주셔서 감사합니다~
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
1:1 연관관계
1:1 연관관계인 두 엔티티가 존재할 경우, 사실 1개의 테이블로 관리할 수 있고, 2개의 테이블 분리해서 관리할 수 있는데, 두 엔티티를 분리하는게 더 나을 것 같아서 2개의 엔티티로 분리하는 걸까요?
-
해결됨자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
안녕하세요. 강의 후 개인적으로 학습 시 나타나는 NPE관련 질문드립니다.
안녕하세요! 강의를 완강 후 혼자 프로젝트를 진행하다 도서 대출 코드를 보고 비슷하게 구현한 사용자가 채용공고를 지원하는 메소드를 호출시 테스트 코드에서 NPE가 발생하는데 혹시 이유를 알 수 있을까요? 여러가지 서칭해봐도 해결이 안되서 질문드립니다... ㅠㅠ회원entity@Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "users") @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id") private Long id; private String name; @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private List<ApplyHistory> applyHistory = new ArrayList<>(); public void applyCompany(JobPosting jobPosting) { this.applyHistory.add(new ApplyHistory(this, jobPosting)); } @Builder private User(Long id, String name, List<ApplyHistory> applyHistory) { this.id = id; this.name = name; this.applyHistory = applyHistory; } }ApplyHistory entity(JobPosting과 user객체가 N:M 매핑해주는 entity)@Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "apply_history") @Entity public class ApplyHistory { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "apply_history_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User user; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "job_posting_id") private JobPosting jobPosting; public ApplyHistory(User user, JobPosting jobPosting) { this.user = user; this.jobPosting = jobPosting; } } JobPosting Entity@Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "job_posting") @Entity public class JobPosting { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "job_posting_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "company_id") private Company company; @Column(name = "posting_position") private String position; private int compensation; //채용보상금 @Column(name = "posting_details") private String postingDetails; @Column(name = "technology_used") private String technologyUsed; @Builder private JobPosting(Company company, String position, int compensation, String postingDetails, String technologyUsed) { this.company = company; this.position = position; this.compensation = compensation; this.postingDetails = postingDetails; this.technologyUsed = technologyUsed; } public void updateJobPosting(String position, int compensation, String postingDetails, String technologyUsed) { this.position = position; this.compensation = compensation; this.postingDetails = postingDetails; this.technologyUsed = technologyUsed; } } applyService@RequiredArgsConstructor @Service public class ApplyService { private final JobPostingRepository jobPostingRepository; private final UserRepository userRepository; private final ApplyHistoryRepository userJobPostingRepository; @Transactional public void applyCompany(ApplyCompanyRequest request) { // 1. 채용공고 정보 찾기 JobPosting jobPosting = jobPostingRepository.findById(request.getJobPostingId()) .orElseThrow(() -> new ResourceNotFoundException("jobPosting", request.getJobPostingId())); // 2. 유저 정보 가져오기 User user = userRepository.findById(request.getUserId()) .orElseThrow(() -> new ResourceNotFoundException("user", request.getUserId())); // 3. 지원 유무 확인 // 3-1. 지원 중이면 예외 발생 if (userJobPostingRepository.existsByJobPostingAndUser(jobPosting, user)) { throw new IllegalArgumentException("이미 지원하신 회사입니다."); } user.applyCompany(jobPosting); } } 리퀘스트@Getter @Setter public class ApplyCompanyRequest { private Long jobPostingId; private Long userId; } 서비스 테스트 코드@SpringBootTest class ApplyServiceTest { @Autowired JobPostingService jobPostingService; @Autowired ApplyService applyService; @Autowired JobPostingRepository jobPostingRepository; @Autowired UserRepository userRepository; @Autowired ApplyHistoryRepository applyHistoryRepository; @Autowired CompanyRepository companyRepository; @AfterEach void tearDown() { applyHistoryRepository.deleteAllInBatch(); jobPostingRepository.deleteAllInBatch(); userRepository.deleteAllInBatch(); companyRepository.deleteAllInBatch(); } @DisplayName("사용자는 채용 공고를 지원 할 수 있다.") @Test @Transactional void applyCompany() { //given User user = User.builder() .id(1L) .name("jw") .build(); User savedUser = userRepository.save(user); Company company = Company.builder() .name("company1") .country(Country.KOREA) .city(City.SEOUL) .build(); Company savedCompany = companyRepository.save(company); JobPosting jobPosting = JobPosting.builder() .company(savedCompany) .position("백엔드") .postingDetails("백엔드 개발자 채용합니다.") .compensation(500000) .technologyUsed("Java") .build(); JobPosting savedJobPosting = jobPostingRepository.save(jobPosting); ApplyCompanyRequest request = new ApplyCompanyRequest(); request.setUserId(savedUser.getId()); request.setJobPostingId(savedJobPosting.getId()); //when applyService.applyCompany(request); //then } } -> 이부분에서 applyCompany(request) 호출 시 NPE가 발생합니다.java.lang.NullPointerException at com.wanted.findjob.domain.user.User.applyCompany(User.java:36) at com.wanted.findjob.api.service.ApplyService.applyCompany(ApplyService.java:39) at com.wanted.findjob.api.service.ApplyService$$FastClassBySpringCGLIB$$2f4064b0.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:792) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:707) at com.wanted.findjob.api.service.ApplyService$$EnhancerBySpringCGLIB$$81701d47.applyCompany(<generated>) at com.wanted.findjob.api.service.ApplyServiceTest.applyCompany(ApplyServiceTest.java:83) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84) at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base/java.util.ArrayList.forEach(ArrayList.java:1540) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base/java.util.ArrayList.forEach(ArrayList.java:1540) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55) 테스트코드가 아닌 직접 서버를 작동해서 api를 호출 시 정상적으로 db에 들어가는 걸 볼 수 있는데 어디가 문제 인지를 모르겠습니다.. ㅠ
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
lombok 플러그인 관련 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]13:08 에 롬복 플러그인을 깔라고 하셨는데 플러그인에서 lombok을 검색해도 나오지 않아서 질문드립니다. 안깔아도 되는건가요??
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
일대일 대상 테이블에 외래키 단방향 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]비지니스적으로 많이 사용되는 빈도를 기준으로 MEMBER가 주 테이블, LOCKER가 대상 테이블이라고 이해하였습니다.위 그림에서 LOCKER(대상 테이블)에 외래 키가 있고, Member객체가 Locker 객체를 참조하고 있으므로 Member객체가 연관 관계의 주인이 됩니다. 그런데, LOCKER 테이블에 외래 키가 있으므로 연관 관계의 주인은 Locker객체가 되어야 하지 않나요?
-
미해결쥬쥬와 함께 하루만에 시작하는 백엔드 - 스프링, 도커, AWS
2-3 진행중 에러
안녕하세요 강의 잘 듣고 있습니다. 2-3 DELETE 과정 중 500에러가 발생하는 데 이유가 뭘까요?
-
미해결호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)
안녕하세요!
혹시 시즌3 자료는 받을수 없을까요?!
-
미해결호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)
SecurityFilterChain 서블릿 매핑 오류 관련...
@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{return http.authorizeHttpRequests().requestMatchers("/auth/login").permitAll() .anyRequest().authenticated() .and().csrf(AbstractHttpConfigurer::disable) .build(); }기존의 강의에 나온 위 코드를 실행하게 되면, This is because there is more than one mappable servlet in your servlet context: {org.springframework.web.servlet.DispatcherServlet=[/], org.h2.server.web.JakartaWebServlet=[/h2-console/*]}.위와 같은 DispatcherServlet과 h2-console의 서블릿이 하나 이상 매핑되어 나는 오류라고 나옵니다.@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception{ http.authorizeHttpRequests((authz) -> { try { authz .requestMatchers(new MvcRequestMatcher(introspector,"/auth/login")).permitAll() //애는 권한 없이도 허용 .anyRequest().authenticated() //나머지는 인증해 .and() //csrf쪽으로는 builder가 이어지지 않기 때문에 and로 이어준다. .csrf(AbstractHttpConfigurer::disable); } catch (Exception e) { throw new RuntimeException(e); } }); return http.build(); }그래서 검색 결과 위와 같이 작성하게 되면 정상적으로 실행되게 됩니다.- 질문제가 코드를 기존에 SecurityFilterChain 외 잘못 작성한 부분이 존재해서 위와 같이 코드를 작성해야 하는 것인지, 아니면 그 사이에 이렇게 작성되도록 변경된 것인지 앞으로도 지속적으로 검색해보겠지만... 현재까진 답을 찾지 못해 질문드립니다.2. h2-console의 경우 데이터베이스 관련 서블릿이고, DispatcherServlet은 웹 애플리케이션의 컨트롤러 역할을 하는 서블릿인걸로 알고 있는데 용도가 다른 두 서블릿의 매핑 혼동이 일어나는 이유가 궁금합니다...*무지한 한 생명체의 질문은 천천히 쾌차하시고 삶의 여유를 되찾으신 다음 답변해주시면 감사하겠습니다!
-
미해결Practical Testing: 실용적인 테스트 가이드
Repository 구현시 @Repository 어노테이션을 붙이는 이유가 궁금합니다.
안녕하세요, 우빈님 너무 좋은 강의를 올려주셔서 잘 듣고 있습니다! Repository 구현 시 @Repository 어노테이션을 붙이는 이유가 궁금합니다.스프링 데이터 JPA를 사용할 경우 스프링이 만들어서 제공하는 컴포넌트를 사용해서 @Repository 를 생략해도 되는 거로 알고 있는데, 사용하시는 이유가 따로 있는지 궁금합니다.
-
미해결스프링과 JPA 기반 웹 애플리케이션 개발
이미지 경로 저장, 로직 문의
profileImage 를 저장할때 엄청 긴 값을 저장 시키는데막상 DB를 보면 이런값이 있는데이건 스프링 부트가 알아서 변환 시켜주는건가요 ?
-
미해결스프링과 JPA 기반 웹 애플리케이션 개발
autocomplete 질문
질문 1 안녕하세요 강의 재밌게 잘 보고있습니다.ajax 하실때 저 부분은 왜 넣어주신건가요 ? autocomplete: {enabled: true,rightKey: true,}, 이코드는 무슨 이유 때문에 쓰신건지 궁금합니다 ! 혹시 ajax 부분이 아니라 여기에 추가 시키는게 아닌가요 ?!? 질문 2설정 해주신 부분중에application.properties 에는 spring.profiles.active=local를 추가시켜주셨고 인텔리제이 기능으로 Actice profiles : dev 를 주셨는데 한쪽은 local 로 세팅다른 한쪽은 dev 최종 dev가 적용이 된거같은데그럼 인텔리제이 에서 세팅(Edit Configuration Settings)한 부분이 더 우선 순위가 높다고 생각하면 되는건가요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
영속성 전이
영속성 전이를 사용해야할 경우에 대해서 2가지 조건을 언급하셨는데,1) 단일 소유자일 때2) parent와 child의 lifecycle이 유사할 때, 그러면, 영속성 전이가 필요 없는 경우는게시판에서 글과 댓글이 있을 때, 글과 댓글이 생명주기가 같지 않을 경우, 예를 들어, 글이 삭제되었어도, 데이터 수집을 위해 댓글은삭제되지 않는 다는 정책이 있다면, 굳이 영속성 전이가 필요없을까요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
JPQL DB 바로 조회
JPQL를 데이터를 조회하면, DB에 먼저 조회한 후, 영속성 컨텍스트에 이미 동일한 엔티티가 있으면, DB에서 조회한 데이터를 버리고, 이미 있는 엔티티를 반환한다고 알고 있습니다.만약, 기존 엔티티를 새로 검색한 엔티티로 대체한다면, 영속성 컨텍스트에 수정 중인 데이터가 사라질 수 있어, 위험하다고 하는데, 그러면, 조회시 수정 중인 데이터가 조회되어서, 의도치 않는 데이터가 조회될 수 있지 않나요? 오히려 수정 중인 데이터 대신 새로 조회한 데이터로 대체하는게 좋지 않을까 싶은데, 혹시, DB에서 조회한 데이터를 버리고, 이미 있는 엔티티를 반환하는게 더 장점인 구체적인 예시가 있을까요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
영속성 전이 관련해서 궁금한 점이 있습니다.
Child child1 = new Child(); Child child2 = new Child(); Parent parent = new Parent(); child1.setParent(parent); // 필수? child2.setParent(parent); // 필수? parent.getChildren().add(child1); parent.getChildren().add(child2); em.persist(parent); Parent와 Child 가 양방향 관계일 때,cascade를 persist 설정을 해줄 경우, 1번의 persisten 호출로 child와 parent 를 DB에 저장하는 것 뿐이지, 서로가 서로를 set은 해줘야 하는 건가요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
실무에서 비교적 자주 사용될 수 있는 연관관계
강의와 책 종합해서 정리하면,실무에서 비교적 자주 사용될 수 있는 연관관계는1:1 - 단방향, 양방향다:1 - 단방향, 양방향밖에 없는 것 같은데, 맞을까요? 다:다는 일대다, 다대일로 관계를 풀어야 하고,1:다의 단방향은 이상한 구조이고,1:다의 양방향은 존재하지 않고, 대신 다:1 양방향 매핑을 사용해서, 결국 위와 같은 연관관계만 남는게 아닌가 싶어서 여쭤봅니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
연관관계 주인 정하기
다:1, 1:다, 1:1, 다:다 등 어느 경우든지 간에 양방향 관계라면, 연관 관계의 주인을 정해야 하는 건가요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
준영속상태로 변경된 엔티티의 관리
엔티티의 생명주기 공부하다 궁금한점이 있습니다.준영속상태로 변경된 경우, 엔티티는 계속 메모리에 올라와 있나요? 아니면 CG 처럼 누군가가 불필요하다고 판단되면 엔티티를 삭제 하나요?
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
lombok 관련 오류입니다
BookService에서 @RequiredArgsConstructor을 설정하면책 대출, 책 반납 등 BookRepository를 사용하는 코드에서 에러가 발생합니다. 오류 메시지는 "this.bookRepository" is null입니다. BookService에서 bookRepository가 받아오지 못하는 것 같습니다.또한, 해당 어노테이션을 지운 후 생성자로 변경하면, 코드는 정상적으로 돌아가게 됩니다. Lombok의 문제인 건지, 코드의 특정 부분을 설정하면 되는 것인지 궁금합니다.