반응형

Spring Boot QueryDSL 초기 설정

Quesrydsl 을 사용하기 위해서는 SpringDataJPA도 추가해야 함

build.gradle 설정 추가

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'

	// H2 Database
	runtimeOnly 'com.h2database:h2'

	// QueryDSL
	implementation 'com.querydsl:querydsl-jpa:5.0.0'
	annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jpa"    // querydsl JPAAnnotationProcessor 사용 지정
	annotationProcessor "jakarta.persistence:jakarta.persistence-api"	// java.lang.NoClassDefFoundError(javax.annotation.Entity) 발생 대응
	annotationProcessor "jakarta.annotation:jakarta.annotation-api"		// java.lang.NoClassDefFoundError (javax.annotation.Generated) 발생 대응
	
}

/** clean 태스크 실행시 QClass 삭제 */
clean {
	delete file('src/main/generated') // 인텔리제이 Annotation processor 생성물 생성위치
}

IntelliJ에서 프로젝트 실행시, 엔티티 클래스 앞에 Q가 붙은 Q클래스가 생성이 되는데 이는 IntelliJ 설정에 따라 생성되는 위치가 다르다.

IntelliJ IDEA에서 빌드방식 선택(Gradle or IntelliJ IDEA에 따라 ‘Querydsl Annotation processor’ 가 생성하는 Q클래스의 위치가 달라지기 때문이다.

Gradle 로 설정시

  • Qclass 생성경로: build/generated/sources/annotationProcessor/java/main
  • Q클래스에 대한 별도 정리 작업 없이 Clean태스크로 정리 된다.

IntelliJ IDEA로 설정시

  • Qclass 생성경로: src/main/generated
  • Compiler Annotation procesoors 설정영향받음
  • 기존 생성된 Q클래스는 갱신되지만 엔티티 위치 변경이나 삭제된 경우 기존Q클래스는 그대로 유지된다
  • src/main/generated 폴더에 생성된 Q클래스 처리 태스크를 작성 해야 한다.

  • IntelliJ IDE 설정으로 사용시 github로 버전관리를 하면 generated 경로 파일이 올라가지 않도록 .gitignore에 추가해주도록 하자. (generated)

[참고자료]

https://gaemi606.tistory.com/entry/Spring-Boot-Querydsl-추가-Gradle-7x

http://honeymon.io/tech/2020/07/09/gradle-annotation-processor-with-querydsl.html

반응형

롬복(Lombok) 라이브러리를 사용하면 getter,setter,builder,constructor 코드를 프로젝트 컴파일 시 관련 코드를 자동으로 작성해준다. 코드의 양을 줄이고 개발시간을 단축시켜줌

1. IntelliJ에서 Preferences(⌘,) 창에서 Plugins → lombok 설치

2. 롬복 디펜던시 설정

builder.gradle 파일에 디펜던시 부분 추가

compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

3. 어노테이션 프로세싱 설정

Gradle이 아닌 IntelliJ에서 인식하도록 어노테이션 프로세싱을 설정해 주자

Preferences(⌘,) → Build, Execution... → Compiler → Annotation Processors

상단의 Enable annotation processing 항목 체크박스에 체크해주자

4. 컴파일 테스트 확인

아래 코드를 작성하여 에러 없이 컴파일이 된다면 정상 셋팅 완료

package com.pmguda.demo;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
public class DemoDTO {
    private String id;
}

어노테이션 설명

@Builder : 오브젝트 생성을 위한 디자인 패턴, Builder 패턴을 사용해 오브젝트 생성

DemoDTO dto = DemoDTO.builder().id("testId").build();

@NoArgsConstructor : 매개변수가 없는 생성자를 구현

@AllArgsConstructor : 클래스의 모든 멤버 변수를 매개변수로 받는 생성자 구현

@Data : 클래스의 멤버 변수의 Getter/Setter 메서드를 구현

반응형

 

1. @EnableScheduling 어노테이션 추가

  • @SpringBootApplication 어노테이션이 있는 Application.java 파일에 @EnableScheduling 어노테이션 추가
@SpringBootApplication
@EnableScheduling
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

}

 

2. Scheduler.java 파일 생성

  • Scheduler 클래스에 @Component 어노테이션 추가

3. 메소드 작성 및 @ Scheduled 어노테이션 작성 (크론표현식 이용)

  • @Scheduled(cron = "0 */5 * * * *") 5분주기
@Component
@Slf4j
public class Scheduler {
	
	@Scheduled(cron = "0 * * * * *")	// 1분마다
	public void test1() throws Exception {
		log.info("1분마다 수행");
	}

	@Scheduled(cron = "0 */5 * * * *")	// 5분마다
	public void test2() throws Exception {
			log.info("5분마다 수행");
	}

	@Scheduled(cron = "0 0 0 * * *")	// 매일 00시 정각
	public void test3() throws Exception {		
		log.info("매일 00시 수행");
	}
	
}
반응형

0. 개발환경

  • Spring Boot 2.6.0
  • Gradle
  • Java11
  • H2 Database
  • IntelliJ

1. build.gradle 의존성 추가

runtimeOnly 'com.h2database:h2'

implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'

2. src/main/resources/log4jdbc.log4j2.properties 파일 추가

log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
log4jdbc.dump.sql.maxlinelength=0

3. application.properties H2 database 설정 수정

spring.datasource.url=jdbc:log4jdbc:h2:mem:test
spring.datasource.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy

4. src/main/resources/logback.xml 파일 생성

<configuration>
    <!-- Appender, 출력 형식 지정 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d{yyyy.MM.dd HH:mm:ss.SSS} {%thread} %-5level %logger{5} - %msg %n</pattern>
            </encoder>
    </appender>
    <logger name="jdbc.resultsettable" level="DEBUG" />
    <logger name="jdbc.sqltiming" level="DEBUG" />
    <logger name="jdbc.resultset" level="OFF" />
    <logger name="jdbc.sqlonly" level="OFF" />
    <logger name="jdbc.audit" level="OFF" />
    <logger name="jdbc.connection" level="OFF" />

    <root level="INFO">
        <appender-ref ref="console"></appender-ref>
    </root>
</configuration>
반응형

SpringBoot에서 jpa를 사용하여 Entity를 생성시에 @Entity 어노테이션을 사용하여 DDL이 자동으로 생성되도록 설정을 하였고

초기 데이터 적재를 위해 resource 디렉토리 아래 data.sql 파일에 insert 문을 넣고 실행시 아래 에러가 발생했다.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of URL [file:/Users/guda/dev/SpringBoot/workspace/demo/out/production/resources/data.sql]: INSERT INTO book (`title`, `author`, `price`) VALUES ('지금 이대로 좋다', '법류 저', 9330); nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "BOOK" not found; SQL statement:

처음 공부하는 환경에서 하다 보니 하루동안 삽질 하면서 어떤 문제인지 엄청 삽질을 했다

실행환경 SpringBoot(2.6.4) + Gradle(7.4) + H2(database 2.1.4) + JPA(2.6.4)

결론은 스프링 2.5부터 SQL Script DataSource Initialization이 변경되면서 발생된 문제였다.
schema.sql 및 data.sql 스크립트를 지원하는 데 사용되는 기본 방법이 Spring Boot 2.5에서 재설계되었단다. 

참고한 내용들이 2.5 이전 버전 설정들이여서 정상적으로 작동한 것이다.

해결방안은 application.properties 파일에 아래 설정 값을 추가 하면 된다.

spring.jpa.defer-datasource-initialization=true

 

<참고사항>

Spring Boot 2.5 Release Notes 를 참고해 보면 아래 와 같은 내용이 나온다.
(https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.5-Release-Notes#hibernate-and-datasql)

기본적으로 data.sql 스크립트는 이제 Hibernate 초기화되기 전에 실행된다.
data.sql 사용하여 Hibernate 의해 생성된 스키마를 채우려면 spring.jpa.defer-datasource-initialization true 설정해라.
데이터베이스 초기화 기술을 혼합하는 것은 권장되지 않지만 이는 data.sql 통해 채우기 전에 하이버네이트에서 생성한 스키마를 기반으로 schema.sql 스크립트를 사용할 수도 있습니다.

Hibernate and data.sql

By default, data.sql scripts are now run before Hibernate is initialized. This aligns the behavior of basic script-based initialization with that of Flyway and Liquibase. If you want to use data.sql to populate a schema created by Hibernate, set spring.jpa.defer-datasource-initialization to true. While mixing database initialization technologies is not recommended, this will also allow you to use a schema.sql script to build upon a Hibernate-created schema before it’s populated via data.sql.

 

반응형

이클립스에서 SVN 사용시 업데이트 또는 커밋시 Checksum 관련 에러가 간혹 발생한다.

svn: Checksum mismatch for while updating 

또는

svn: Working copy 'xxxxxxxxxxx' locked; try performing 'cleanup'

위와 같은 에러 발생시 해결 방안

1. 프로젝트 Cleanup
   1) 해당하는 프로젝트 우클릭 > Team > Cleanup

위 방법으로 해결이 안될 시 아래 방법 시도

2. 탐색기로 해당 파일이 있는 폴더 삭제(주의요망!!)
   1) 탐색기로 해당하는 프로젝트 접근 > svn 에러가 발생한 상위 폴더 삭제
    (예로 testSrc/test.jsp 에서 에러가 발생했다면 testSrc 폴더를 삭제)
    !!주의  절대 이클립스로 삭제하면 안됨. 탐색기에서 삭제 해야 한다.

   2) 이클립스의 svn으로 다시 싱크를 맞추고 진행

 

 

반응형

JComboBox에서 선택된 값을 리턴하는 메소드를 찾아보니 없는거 같다.

별것 아닌거 같지만 이런게 없어 하는 의아한 생각이 든다.

다른메소드를 이용하여 가져오는게 가능하니 만들지 않았을 수도 있지만

이러한 경우는 많이 사용하기 때문에 있는것이 당연하지 않나 하는 의문이 든다.

므튼 메소드가 없기 때문에(내가 찾지 못했을 수도?) 방법을 정리해보자.

나중에 까먹고 그 메소드를 찾기위해 API를 또 찾기 때문에 (있을텐데 ?? 하면서 )

jcombo.getSelectedItem().toString()

jcombo.getItemAt(jcombo.getSelectedIndex()).toString()

  1. Favicon of http://tvple.me/animation BlogIcon 애니다시보기 2020.08.31 15:40

    잘 보고 갑니다...

  2. 1 2021.03.02 11:18

    우울하노

반응형

스윙으로 GUI를 만들어 리스너에 코딩을 하고 했는데 코딩상에서 해당 컴포넌트에 걸린 이벤트를

실행하려고 별짓을 다 했다. ㅡㅡ; 그냥 이벤트 내에 들어가는 코딩을 메소드로 만들어 메소드를 호출하기도..

이건 아니다 싶어 이벤트 생성하여 해당 리스너를 참조하여 

 testListener.actionPerformed(new ActionEvent(jBtntest,ActionEvent.ACTION_PERFORMED, "openEvent"));

이렇게 해서 사용했다.. 대충 이렇게 하는게 낫나 싶어서 .. 므튼 이리저리 찾다보니 관련 자료를 찾았다.
 

원문: http://mindprod.com/jgloss/event11.html#SYNTHETICEVENTS

참조: http://www.codeguru.com/java/articles/162.shtml

JButton은 보통 doClick() 메소드를 이용하여 처리하면 되지만 다른 방법도 있으니 알아보자.

내가 주로 사용했던 방법은 2번 이었음..^^; 뭐 편법은 아닌듯.. ㅋㅋ

원문에서 필요한 부분만 발췌 하였음..

There are a number of ways to fake an event.

2) The simplest is just to call a Listener method directly with a dummy Event object, filled in with just enough data to keep the method happy.

3)Create an Event and introduce it to the Component that will handle it at the processEvent method. with:

 4)Create an Event 

 

 5)Generating MouseMoved Events has no effect on the screen mouse cursor. To make the underlying native GUI see your generated Events, use the Robot class to generate move clicks, moves etc. 

기본적으로 버튼에 따른 이벤트를 실행한다면 doClick()을 사용해야겠다.
그리고 일단 막히면 API 부터 제대로 뒤져봐야겠다 ㅡㅡ; 끙.. doClick 모르고 있었다는 ㅡㅡ;

2010.11.03  추가
오랫만에 기존에 작성했던 프로그램에 간단한 수정을 하면서 이벤트를 강제로 발생하는 부분을 검색

내가 기존에 포스팅 했던 글이 뜬다. ㅡㅡ;  예전에 몰라서 포스팅한걸 지금도 까먹다니 ㅠㅠ

그래서 조금 내용을 추가하여 갱신하기로 했다. 다시한번 잘 정리한다는 생각으로..^^

 

반응형
입력받은 클래스명으로 해당 클래스를 생성하는 코드이다.

클래스: java.lang.Class<T>
메소드:
static Class<> forName(String className)
//->지정된 캐릭터 라인명을 가지는 클래스 또는 인터페이스에 관련지을 수 있던,Class 객체를 돌려준다.
newInstance()  //-> 이 Class객체가 나타내는 클래스의 새로운 인스턴스 생성.

반응형

+ Recent posts