작성
·
1.5K
·
수정됨
0
1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)
[질문 내용]
질문 1)
실전 스프링 Data JPA -
섹션 1. 프로젝트 환경설정 -스프링 데이터 JPA와 DB설정, 동작확인 강의에서
H2 데이터베이스 설치 후 , 동일하게 memberJpaRepositoryTest 한 후
H2 데이터베이스 다시 접속하여 확인하여도 , member table 이 생성되어 있지 않습니다.
콘솔창에 찍히는걸 봤을때는 insert까지 잘 된것을 확인했습니다만
무엇이 문제일까요?
[Member ].class
package com.example.datajpa.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import lombok.Getter;
@Entity
@Getter
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
private String name;
public Member(String name) {
this.name = name;
}
//디폴트값으로 private 하기엔 프록시 생성시 사용되어야 함으로 protected 제어자를 통해 다른곳에서 만들지 못하도록함
protected Member() {
}
}
[MemberJpaRepository] .class
@Repository
public class MemberJpaRepository {
@PersistenceContext
private EntityManager em; //jpa의 영속성컨텍스트를 관리 하는 엔티티메니저, 이것에 의해 데이터를 관리함.
public Member save(Member member ){
em.persist(member);// 영속화
return member;
}
public Member find(Long id){
return em.find(Member.class,id);
}
}
[MemberJpaRepositoryTest] .class
@SpringBootTest
@Transactional // 테스트가 끝난후 데이터를 롤백하기 위해
@Rollback(false) // 만약 롤백을 원하지 않을경우엔 이 어노테이션을 사용함, 실전에서는 ! 사용 노노!
class MemberJpaRepositoryTest {
@Autowired
MemberJpaRepository memberJpaRepository;
@Test
public void testMember(){ //public 생략가능
Member member = new Member("memberA");
Member savedMember = memberJpaRepository.save(member);
Member findMember = memberJpaRepository.find(savedMember.getId());
assertThat(findMember.getName()).isEqualTo(member.getName());
assertThat(findMember.getId()).isEqualTo(member.getId());
assertThat(findMember).isEqualTo(member);
}
}
[application.yml]
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/datajpa
username: sa
password:
driver-class-name: org.h2.Driver
jpa:
hibernate:
ddl-auto: create
# 객체를 보고 자동으로 테이블 생성 여부. 생성 - create, 비생성 - none
# 테스트이기 때문에 create로 설정하며
# 실제로는 none 으로 합니다. create이면 기존의 테이블을 전부 밀어버립니다.
properties:
hibernate:
show_sql: true
format_sql: true
logging.level:
org.hibernate.SQL: debug
# 콘솔창에 파라미터 값을 보고 싶을때 주로 개발할때, 실전에서는 성능저하 가능성 고려하여 사용해야함.
org.hibernate.type: trace
#implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.7' 외부라이브러리 추가하면깔끔하게 파리미터값을 보여준다.
# show_sql : 옵션은 System.out 에 하이버네이트 실행 SQL을 남긴다.
# org.hibernate.SQL : 옵션은 logger를 통해 하이버네이트 실행 SQL을 남긴다.
[build gradle]
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
//h2사용
runtimeOnly 'com.h2database:h2'
[콘솔창]
insert into member (id, name) values (default, ?)
insert into member (id, name) values (default, 'memberA');
2023-05-26 18:33:03.071 INFO 3250 --- [ main] p6spy : #1685093583071 | took 0ms | commit | connection 4| url jdbc:h2:mem:ca9facbe-0495-462f-a2eb-d8f9f1d14ecd
;
2023-05-26 18:33:03.072 INFO 3250 --- [ main] o.s.t.c.transaction.TransactionContext : Committed transaction for test: [DefaultTestContext@3b0c9195 testClass = MemberJpaRepositoryTest, testInstance = com.example.datajpa.repository.MemberJpaRepositoryTest@3f6a9ba0, testMethod = testMember@MemberJpaRepositoryTest, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@366c4480 testClass = MemberJpaRepositoryTest, locations = '{}', classes = '{class com.example.datajpa.DataJpaApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@5c86dbc5, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@5f9edf14, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@a8ef162, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@78fa769e, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@536dbea0, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@6b26e945], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.populatedRequestContextHolder' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.resetRequestContextHolder' -> true, 'org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false]]
2023-05-26 18:33:03.096 INFO 3250 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2023-05-26 18:33:03.097 INFO 3250 --- [ionShutdownHook] .SchemaDropperImpl$DelayedDropActionImpl : HHH000477: Starting delayed evictData of schema as part of SessionFactory shut-down'
2023-05-26 18:33:03.101 INFO 3250 --- [ionShutdownHook] p6spy : #1685093583101 | took 2ms | statement | connection 5| url jdbc:h2:mem:ca9facbe-0495-462f-a2eb-d8f9f1d14ecd
drop table if exists member CASCADE
drop table if exists member CASCADE ;
2023-05-26 18:33:03.106 INFO 3250 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2023-05-26 18:33:03.115 INFO 3250 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
Process finished with exit code 0
질문 2. 이 강의를 보기 전에는 h2데이터베이스 별도 설치 없이
아래와 같이 Application.yml 설정과
Build.gradle에 의존성만 지정하여
브라우저에서 Localhost:8080/h2-console 치면 h2 데이터베이스를 사용할 수 있었습니다.
하지만 이 강의를 따라 h2 설치 후엔 Localhost:8080/h2-console 해도 500에러만 발생합니다. 이유가 뭘까요 ㅠㅠ
[application.yml]
# h2
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:db;MODE=MYSQL;
username: sa
password:
[build gradle]
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
//h2사용
runtimeOnly 'com.h2database:h2'
답변 4
0
0
안녕하세요, 인프런 AI 인턴이에요.
질문1) 문제는 Member 클래스의 생성자에서 매개변수를 받아오지 않는 생성자를 protected 제어자를 통해 선언하여 JPA의 프록시 기술이 동작하도록 설계되었다는 것입니다. 따라서 Member 클래스를 사용하는 부분에서 Member 객체를 직접 new
연산자로 생성하지 않고, memberRepository.save()
와 같은 JPA의 EntityManager.persist() 메소드를 사용하여 객체를 만들어야 합니다. 그렇지 않으면 정확한 프록시 처리가 되지 않습니다.
질문2) 강의에서는 H2 데이터베이스를 설치하고 설정파일(application.yml)에서 URL을 포트와 함께 지정하였기 때문에, localhost:8080/h2-console로 접속하는 것이 아닌 localhost:8080 으로 접속해야 합니다. 이후 H2 데이터베이스 관리 화면에서는 JDBC URL을 입력할 때, jdbc:h2:tcp://localhost/~/datajpa
와 같이 차이가 있을 수 있습니다. 또한, create
, update
, validate
등의 DDL Auto 옵션을 올바로 설정하는지 확인해야 합니다.
그 외에도 프로젝트 내부에 H2 데이터베이스 파일이 저장되는 경로에 따라서 DB 파일을 찾지 못하는 경우가 있습니다. 따라서 데이터베이스 경로 지정에 유의하여 설정해보시기 바랍니다.
감사합니다.
-1
1번은 [application.yml]의
spring:
ㄴ datasource:
이 아래부터 들여쓰기가 안맞아서 inmemory로 동작하는것 같습니다. url, username, password, driver-class-name 옵션을 datasource의 하위에 오도록 한칸씩 들여쓰기 해주세요