반응형

BeanCreationException

Environment

  • Language: Java
  • DB: H2 Database
  • IDE: IntelliJ

 

Problem

Entity에서 PK에 @Id를 설정하고, @GeneratedValue를 통해 자동으로 값을 부여하고자 할 때 발생

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not instantiate id generator [entity-name=jpabook.jpashop.Member]

Caused by: org.hibernate.HibernateException: Could not fetch the SequenceInformation from the database

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "start_value" not found [42122-224]

 

Cause of Problem

strategy 속성을 생략하면 기본적으로 GenerationType.AUTO가 사용됨

Hibernate가 데이터베이스에 맞는 적절한 전략을 자동으로 선택

H2 DB는 IDENTITY, SEQUENCE, TABLE 전략을 모두 지원하므로 IDENTITY, SEQUENCE, TABLE 중 1개가 선택

SEQUENCE없이 GenerationType.SEQUENCE가 실행되어 Could not instantiate id generator 오류가 발생한 것으로 추정

 

Solution

  • @GeneratedValue에 strategy GenerationType.IDENTITY 속성 추가
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.Setter;

@Entity
@Getter @Setter
public class Member {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
}
  • strategy 유형
    • GenerationType.AUTO
      • 기본값
      • 데이터베이스에 맞는 적절한 전략을 자동으로 선택
    • GenerationType.IDENTITY
      • PK 생성을 DB에 위임(예: MySQL-AUTO_INCREMENT)
      • PK에 null값을 넘기면 DB에서 자동으로 생성해줌
    • GenerationType.SEQUENCE
      • Sequence 객체를 생성해서 생성한 Sequence 객체에서 값을 가져와 PK값에 세팅
      • 주로 Oracle, H2에서 지원
    • GenerationType.TABLE
      • 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 사용하는 것처럼 하는 전략
      • 시퀀스를 지원하지 않을 때 사용

 

cf. @Id package 확인

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.Setter;

@Entity
@Getter @Setter
public class Member {

    @Id @GeneratedValue
    private Long id;
    private String username;
}

@Id의 package 경로가 jakarta인지 확인

  • jakarta.persistence.Id
    • the annotation defined by JPA for all its implementations
    • JPA only applies for management of relational data
  • org.springframework.data.annotation.Id
    • currently used by Spring to support mapping for other non relational persistence databases or frameworks
    • it is normally used when dealing with other spring-data projects such as spring-data-mongodb, spring-data-solr, etc

 

📚 참고 자료

What's the difference between javax.persistence.Id and org.springframework.data.annotation.Id?
[JPA_Basic] 기본키 매핑
[JPA] H2의 @GeneratedValue 문제

반응형
반응형

👉 기본 환경

- Language: Java

- IDE: Sublime

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Arrays;
import java.util.Collections;
 
class Solution {
    public String solution(String s) {
        String answer = "";
        char[] sToCharArr = new char[s.length()];
        for(int i=0; i<s.length(); i++){
            sToCharArr[i] = s.charAt(i);
        }
        Arrays.sort(sToCharArr, Collections.reverseOrder());
        
        StringBuilder sb = new StringBuilder();
        for(int i=s.length()-1; i>-1; i--){
            sb.append(sToCharArr[i]);
        }
        answer = sb.toString();
        return answer;
    }
}
 
 

 

 

🖨️오류

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/Solution.java:11: error: no suitable method found for sort(char[],Comparator<Object>)
        Arrays.sort(sToCharArr, Collections.reverseOrder());
              ^
    method Arrays.<T#1>sort(T#1[],Comparator<? super T#1>) is not applicable
      (inference variable T#1 has incompatible bounds
        equality constraints: char
        lower bounds: Object)
    method Arrays.<T#2>sort(T#2[],int,int,Comparator<? super T#2>) is not applicable
      (cannot infer type-variable(s) T#2
        (actual and formal argument lists differ in length))
  where T#1,T#2 are type-variables:
    T#1 extends Object declared in method <T#1>sort(T#1[],Comparator<? super T#1>)
    T#2 extends Object declared in method <T#2>sort(T#2[],int,int,Comparator<? super T#2>)
 
 

 

 

📡 원인

기본형 타입에 대한 Comparator가 존재하지 않음

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.Arrays;
import java.util.Collections;
 
class Solution {
    public String solution(String s) {
        String answer = "";
        String[] sToStringArr = s.split("");
        Arrays.sort(sToStringArr, Collections.reverseOrder());
        
        StringBuilder sb = new StringBuilder();
        for(int i=0; i<sToStringArr.length; i++){
            sb.append(sToStringArr[i]);
        }
        answer = sb.toString();
        return answer;
    }
}
 
 

객체 타입의 배열 사용

 

 

 

📚 참고 자료

 

[자바]no suitable method found for sort(int[],(a,b)->Int[...]a, b)) Arrays.sort(numbers, (a, b) -> Integer.compare(a, b

자바에서 custom comparator를 사용하려고 했는데 에러가 발생했습니다. public String solution(int[] numbers) { Arrays.sort(numbers, (a, b) -> Integer.compare(a, b)); 람다식으로도 사용해보고 compare함수도 사용해보고 했

darkstart.tistory.com

 

반응형
반응형

👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

테스트 코드가 안돌아갑니다.

Transaction이 closed 됐다고 안돌아갑니다😖.

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@SpringBootTest
public class PostServiceTest {
 
    @Autowired
    private PostService postService;
 
    @Autowired
    private PostRepository postRepository;
 
    @Test
    public void DTO데이터_POST테이블_조회(){
        // given
        PostSaveDTO dto = PostSaveDTO.builder()
                .title("서비스 타이틀")
                .content("서비스 컨텐츠")
                .author("서비스 작가")
                .build();
 
        // when
        Long saveId = postService.savePost(dto);
        List<Posts> postList = postRepository.findAllDesc().toList();
 
        // then
        // Dto 클래스가 service.save 메소드에 전달되면, DB에 잘 저장되었는지 검증
        Posts findPost = postList.get(1);
        assertThat(findPost.getTitle()).isEqualTo(dto.getTitle());
        assertThat(findPost.getAuthor()).isEqualTo(dto.getAuthor());
 
    }
}
 
 

 

 

🖨️오류

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl@5c4e86e7 is closed
java.lang.IllegalStateException: org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl@5c4e86e7 is closed
    at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.errorIfClosed(AbstractLogicalConnectionImplementor.java:37)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:142)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:51)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:150)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:177)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:152)
    at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.lambda$scroll$1(JdbcSelectExecutorStandardImpl.java:122)
    at org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess.executeQuery(DeferredResultSetAccess.java:226)
    at org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess.getResultSet(DeferredResultSetAccess.java:163)
    at org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.advanceNext(JdbcValuesResultSetImpl.java:254)
    at org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.processNext(JdbcValuesResultSetImpl.java:134)
    at org.hibernate.sql.results.jdbc.internal.AbstractJdbcValues.next(AbstractJdbcValues.java:19)
    at org.hibernate.sql.results.internal.RowProcessingStateStandardImpl.next(RowProcessingStateStandardImpl.java:66)
    at org.hibernate.internal.ScrollableResultsImpl.next(ScrollableResultsImpl.java:51)
    at org.hibernate.query.internal.ScrollableResultsIterator.hasNext(ScrollableResultsIterator.java:33)
    at java.base/java.util.Iterator.forEachRemaining(Iterator.java:132)
    at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1845)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575)
    at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
    at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616)
    at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622)
    at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627)
    at com.project.mini1.webservice.PostServiceTest.DTO데이터_POST테이블_조회(PostServiceTest.java:58)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
    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:156)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
    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.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
    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:1511)
    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:1511)
    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.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:110)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:90)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:85)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
    at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
 

 

 

📡 원인

테스트 실행 중에 이미 다른 곳에서 해당 연결(LogicalConnection)을 닫음

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@SpringBootTest
public class PostServiceTest {
 
    @Autowired
    private PostService postService;
 
    @Autowired
    private PostRepository postRepository;
 
    @Test
    public void DTO데이터_POST테이블_저장(){
        // given
        PostSaveDTO dto = PostSaveDTO.builder()
                .title("서비스 타이틀")
                .content("서비스 컨텐츠")
                .author("서비스 작가")
                .build();
 
        // when
        Long saveId = postService.savePost(dto);
        Posts findPost = postRepository.findOne(saveId);
 
        // then
        // Dto 클래스가 service.save 메소드에 전달되면, DB에 잘 저장되었는지 검증
        assertThat(findPost.getTitle()).isEqualTo(dto.getTitle());
        assertThat(findPost.getContent()).isEqualTo(dto.getContent());
        assertThat(findPost.getAuthor()).isEqualTo(dto.getAuthor());
 
    }
 
    @Test
    public void DTO데이터_POST테이블_조회(){
        // given
        PostSaveDTO dto = PostSaveDTO.builder()
                .title("서비스 타이틀")
                .content("서비스 컨텐츠")
                .author("서비스 작가")
                .build();
        Long saveId = postService.savePost(dto);
 
        // when
        List<PostsMainResponseDTO> postList = postService.findAllPostsDesc();
 
        // then
        // Dto 클래스가 service.save 메소드에 전달되면, DB에 잘 저장되었는지 검증
        PostsMainResponseDTO findPostDTO = postList.get(1);
        assertThat(findPostDTO.getTitle()).isEqualTo(dto.getTitle());
        assertThat(findPostDTO.getAuthor()).isEqualTo(dto.getAuthor());
 
    }
}
 
 

postRepository.findAllDesc().toList() → postService.findAllPostsDesc()

- postRepository.findAllDesc().toList()

    - toList()를 호출하여 스트림을 리스트로 변환하려고 하는데, 이 과정에서 실제 데이터베이스 연결(LogicalConnection)을 사용

    - 테스트 실행 중에 이미 postPost(dto)에서 해당 연결(LogicalConnection)을 닫음

        → org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl@5784f6b9 is closed 에러가 발생

- postService.findAllPostsDesc()

    - 트랜잭션 처리가 자동으로 이루어짐(findAllPostsDesc: @Transactional(readOnly=true) 선언 됨)

        = @Transactional이 선언되어 있으므로 새로운 트랜잭션을 열고 데이터베이스 연결을 유지

 

반응형
반응형

👉 기본 환경

- Language: Java

- DB: MySQL

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.1.4'
    id 'io.spring.dependency-management' version '1.1.3'
}
 
group = 'com.project'
version = '0.0.1-SNAPSHOT'
 
java {
    sourceCompatibility = '17'
}
 
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}
 
repositories {
    mavenCentral()
}
 
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
 
    // .jsp
    implementation 'javax.servlet:jstl'
    implementation "org.apache.tomcat.embed:tomcat-embed-jasper"
 
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'com.mysql:mysql-connector-j'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
 
tasks.named('test') {
    useJUnitPlatform()
}
 
 

 

 

🖨️오류

1
2
3
4
5
6
7
8
9
Execution failed for task ':compileJava'.
> Could not resolve all files for configuration ':compileClasspath'.
   > Could not find javax.servlet:jstl:.
     Required by:
         project :
 
Possible solution:
 - Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
 
 

build.gradle에서 jsp 사용을 위한 jstl이 적용되지 않음

 

 

📡 원인

Springboot 3.대부터는 jstl implementation 방법이 변경됨

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.1.4'
    id 'io.spring.dependency-management' version '1.1.3'
}
 
group = 'com.project'
version = '0.0.1-SNAPSHOT'
 
java {
    sourceCompatibility = '17'
}
 
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}
 
repositories {
    mavenCentral()
}
 
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
 
    // .jsp
    // implementation 'javax.servlet:jstl' //스프링부트 3.0 미만
    implementation 'jakarta.servlet:jakarta.servlet-api' //스프링부트 3.0 이상
    implementation 'jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api' //스프링부트 3.0 이상
    implementation 'org.glassfish.web:jakarta.servlet.jsp.jstl' //스프링부트 3.0 이상
    implementation "org.apache.tomcat.embed:tomcat-embed-jasper"
 
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'com.mysql:mysql-connector-j'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
 
tasks.named('test') {
    useJUnitPlatform()
}
 
 

Springboot 3.대에서 사용할 수 있게 jstl implementation 변경

 

 

⭐ GPT도 좋지만, Google 검색을 다양하게 시도해보자 ⭐

 

 

 

📚 참고 자료

 

(spring 3.0 version) jstl 이 재대로 적용되지 않을때 - 인프런 | 고민있어요

혹시나 spring 3.0 버전을 사용하고 계신분이라면implementation 'javax.servlet:jstl'대신에implementation group: 'org.glassfish.web', name: 'jakarta.servlet.jsp.jstl', version...

www.inflearn.com

 

반응형
반응형

이 글은 김영한의 [자바 ORM 표준 JPA 프로그래밍 - 기본편] 수강하며 정리한 글입니다.

 

👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

Bulk 연산

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class Main {
    public static void main(String[] args) {
 
        // 생략
 
        try {
 
            Team teamA = new Team();
            teamA.setName("TeamA");
            em.persist(teamA);
 
            Team teamB = new Team();
            teamB.setName("TeamB");
            em.persist(teamB);
 
 
            Member memberA = new Member();
            memberA.setName("MemberA");
            memberA.setTeam(teamA);
            em.persist(memberA);
 
            Member memberB = new Member();
            memberB.setName("memberB");
            memberB.setTeam(teamA);
            em.persist(memberB);
 
            Member memberC = new Member();
            memberC.setName("memberC");
            memberC.setTeam(teamB);
            em.persist(memberC);
 
            String query = "update Member m set m.age = 20";
            int resultCnt = em.createQuery(query)
                    .executeUpdate();
 
            System.out.println("ResultCnt: " + resultCnt);
 
            Member findMember = em.find(Member.class, memberA.getId());
 
            System.out.println("memberA.getAge(): " + findMember.getAge());
 
            tx.commit(); // transaction 종료 후 commit
        } catch (Exception e) {
            tx.rollback(); // 문제가 생길 경우, rollback 진행
            e.printStackTrace();
        } finally {
            em.close(); // tx에 문제가 생기더라도 em 반드시 종료
        }
 
 
        emf.close();
        // 트랜잭션 단위로 관리되는 Entity Manager는 Tx가 종료되면 close가 되어야하지만, emf는 Application 종료 시, close되어야 함
 
    }
}
 

- executeUpdate()

    - 벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리 전송

        - DB: memberA.getAge()는 20

        - 영속성 Context: memberA.getAge()는 20이 아닌 0으로 조회

 

🖨️발생한 쿼리

1
2
3
4
5
6
7
8
9
10
11
Hibernate: 
    /* update
        Member m 
    set
        m.age = 20 */ update
            Member 
        set
            age=20
ResultCnt: 3
memberA.getAge(): 0
 
 

 

 

⭐ 벌크 연산 후, 영속성 컨텍스트 초기화

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class Main {
    public static void main(String[] args) {
 
        // 생략
 
        try {
 
            Team teamA = new Team();
            teamA.setName("TeamA");
            em.persist(teamA);
 
            Team teamB = new Team();
            teamB.setName("TeamB");
            em.persist(teamB);
 
 
            Member memberA = new Member();
            memberA.setName("MemberA");
            memberA.setTeam(teamA);
            em.persist(memberA);
 
            Member memberB = new Member();
            memberB.setName("memberB");
            memberB.setTeam(teamA);
            em.persist(memberB);
 
            Member memberC = new Member();
            memberC.setName("memberC");
            memberC.setTeam(teamB);
            em.persist(memberC);
 
            String query = "update Member m set m.age = 20";
            int resultCnt = em.createQuery(query)
                    .executeUpdate();
 
            System.out.println("ResultCnt: " + resultCnt);
 
            em.clear();
 
            Member findMember = em.find(Member.class, memberA.getId());
 
            System.out.println("memberA.getAge(): " + findMember.getAge());
 
            tx.commit(); // transaction 종료 후 commit
        } catch (Exception e) {
            tx.rollback(); // 문제가 생길 경우, rollback 진행
            e.printStackTrace();
        } finally {
            em.close(); // tx에 문제가 생기더라도 em 반드시 종료
        }
 
 
        emf.close();
        // 트랜잭션 단위로 관리되는 Entity Manager는 Tx가 종료되면 close가 되어야하지만, emf는 Application 종료 시, close되어야 함
 
    }
}
 

 

🖨️발생한 쿼리

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Hibernate: 
    /* update
        Member m 
    set
        m.age = 20 */ update
            Member 
        set
            age=20
ResultCnt: 3
Hibernate: 
    select
        member0_.id as id1_0_0_,
        member0_.age as age2_0_0_,
        member0_.name as name3_0_0_,
        member0_.TEAM_ID as team_id5_0_0_,
        member0_.type as type4_0_0_ 
    from
        Member member0_ 
    where
        member0_.id=?
memberA.getAge(): 20
 
 

새로운 select query 발생

 

반응형

'Java > JPA' 카테고리의 다른 글

[JPA_Basic] Fetch Join 2  (0) 2023.09.28
[JPA_Basic] Fetch Join  (0) 2023.09.27
[JPA_Basic] 경로 표현식  (0) 2023.09.26
[JPA_Basic] JPQL 타입 표현과 기타식  (1) 2023.09.25
[JPA_Basic] 조인  (0) 2023.09.23