728x90

duplicateKeyException

Environment
Language: Java
DB: MySQL

 

오류

Caused by: java.lang.IllegalStateException: Duplicate key 400 BAD_REQUEST (attempted merging values DUPLICATED_EMAIL and NOT_EQUAL_PASSWORD)
	at java.base/java.util.stream.Collectors.duplicateKeyException(Collectors.java:135)
	at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:182)

 

 

원인

DUPLICATED_EMAIL(HttpStatus.BAD_REQUEST, "이미 존재하는 이메일 입니다."),
NOT_EQUAL_PASSWORD(HttpStatus.BAD_REQUEST,"입력한 비밀번호가 상이합니다."),

// HttpStatus -> ErrorCode 조회
private static final Map<HttpStatus, ErrorCode> BY_HTTPSTATUS =
        Stream.of(values()).collect(Collectors.toMap(ErrorCode::getHttpStatus, e -> e));

public static Optional<ErrorCode> valueOfHttpStatus(HttpStatus httpStatus){
    return Optional.ofNullable(BY_HTTPSTATUS.get(httpStatus));
}

 

  • toMap()
    • If the mapped keys contain duplicates (according to Object.equals(Object)), an IllegalStateException is thrown when the collection operation is performed. If the mapped keys might have duplicates, use toMap(Function, Function, BinaryOperator) instead.
    • HttpStatus로부터 Enum을 조회하려고 할 때, Map을 활용하는데 이 때 key 값(= HttpStatus)이 중복될 경우, duplicate관련 IllegalStateException이 발생할 수 있음

 

해결

// HttpStatus -> ErrorCode 조회
private static final Map<HttpStatus, ErrorCode> BY_HTTPSTATUS =
        Stream.of(values()).collect(Collectors.toMap(ErrorCode::getHttpStatus, e -> e, ((e1, e2) -> e1)));
        // Stream.of(values()).collect(Collectors.toMap(ErrorCode::getHttpStatus, e -> e, ((e1, e2) -> e2)));

public static Optional<ErrorCode> valueOfHttpStatus(HttpStatus httpStatus){
    return Optional.ofNullable(BY_HTTPSTATUS.get(httpStatus));
}

 

  • toMap(Function, Function, BinaryOperator)
    • BinaryOperator에서 먼저 put할 데이터를 사용할지 나중에 put한 데이터를 사용할지 추가

 

📚 참고 자료

 

[Error/Exception] java.lang.IllegalStateException: Duplicate key ‘key로 저장하려는 값’ (attempted merging values ~~)

에러 발생java.lang.IllegalStateException: **Duplicate key 'key로 저장하려는 값'** (attempted merging values ~~) 오늘도 만난 에러,, 뜯어봐야 알겠지만 대충 봐도 key 값이 중복되어 발생한 에러다.  에러 원인에

hoehen-flug.tistory.com

 

728x90
728x90

EmptyResultDataAccessException

Environment
Language: Java
DB: MySQL

 

오류

Caused by: jakarta.persistence.NoResultException: No result found for query [select u from User u where u.email = :email]
	at org.hibernate.query.spi.AbstractSelectionQuery.getSingleResult(AbstractSelectionQuery.java:476)
	at com.msgs.user.repository.UserRepository.findByEmail(UserRepository.java:19)

 

 

원인

public Optional<User> findByEmail(String email) {
    User user = em.createQuery("select u from User u where u.email = :email", User.class)
            .setParameter("email", email)
            .getSingleResult();
    return Optional.ofNullable(user);
}

 

  • getSingleResult()
  1. 결과가 없을 경우, NoResultException 예외 발생
  2. 결과가 2개 이상일 경우, NonUniqueResultException 예외 발생

 

해결

public Optional<User> findByEmail(String email) {
    List<User> users = em.createQuery("select u from User u where u.email = :email", User.class)
            .setParameter("email", email)
            .getResultList();
    if (users.isEmpty()) {
        return Optional.empty();
    } else {
        return Optional.of(users.get(0));
    }
}

 

  • getSingleResult() → getResultList()

 

728x90
728x90

JdbcTypeRecommendationException

Environment

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

 

Problem

@Entity를 선언하고 table을 create할 때 발생

Caused by: org.hibernate.type.descriptor.java.spi.JdbcTypeRecommendationException: Could not determine recommended JdbcType for Java type 'jpabook.jpashop.domain.Delivery'

 

Cause of Problem

Hibernate가 엔티티의 필드에 대한 JDBC 타입을 결정하지 못할 때 발생

엔티티 필드와 데이터베이스 컬럼 간의 매핑이 충분히 명시되지 않았거나 잘못되었을 때 발생

관계 설정을 하지 않는다면, Hibernate는 해당 관계를 어떻게 매핑해야 하는지 알 수 없게 되어, Java의 데이터 타입을 SQL 데이터베이스의 데이터 타입에 매핑하지 못하고 JdbcTypeRecommendationException이 발생

 

Solution

  • Delivery Entity가 사용된 Entity에서 @OneToMany 등의 관계 설정이 제대로 이뤄졌는지 확인
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter @Setter
public class Member {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "member_id")
    private Long id;

    private String name;

    @Embedded
    private Address address;

    @OneToMany(mappedBy = "member")
    private List<Order> orders = new ArrayList<>();

    private Delivery delivery;

}

 

📚 참고 자료

728x90
728x90

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 문제

728x90
728x90

👉 기본 환경

- 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이 선언되어 있으므로 새로운 트랜잭션을 열고 데이터베이스 연결을 유지

 

728x90