사용자 도구

사이트 도구


gradle:jpa_metamodel_generation

Gradle에서 JPA 2 MetaModel 생성

Hibernate MetamodelGen을 이용하여 JPA2 MetaModel을 생성하는 예를 보여준다. 실제로는 compile 태스크에 들어가는게 좋으나, 현재 지원을 안 해서, 독릭적으로 JavaCompile 태스크를 만들고, 거기서 Annotation Processor만 호출하도록 변경한 것이다.

  • -proc:only 옵션 때문에 실제 컴파일을 하지 않는다.
  • Java 6 이상에서만 작동한다.

QueryDSL

apply plugin: "com.ewerk.gradle.plugins.querydsl"
 
compile "com.querydsl:querydsl-jpa:$queryDslVersion"
 
 
ext {
    querydslSrcDir = 'src/main/generated'
}
 
 
querydsl {
    library = "com.querydsl:querydsl-apt"
    jpa = true
    querydslSourcesDir = querydslSrcDir
}
 
sourceSets {
    main {
        java {
            srcDirs += file(querydslSrcDir)
        }
    }
}
 
idea {
    module {
        generatedSourceDirs += file(querydslSrcDir)
    }
}
  • compileQueryDsl task로 코드 생성을 할 수 있다.
    gradlew clean cleanQuerydslSourcesDir compileQueryDsl
     
    # cleanQuerydslSourcesDir 를 하지 않을 경우 기존 생성된 코드 때문에 오류가 발생함.

Cannot find symbol 오류

  • QueryDSL과 Hibernate/Eclipse Metamodel Generator를 함께 사용할 때 아직 생성되지 않은 메타 모델 클래스를 사용하는 코드들 때문에 cannot find symbol 에러가 발생할 수 있는데, 이는 이 둘을 서로 따로 생성했을 때 발생하는 현상이다.
  • 정황상 Lombok을 함께 사용할 경우 각 AP가 실행된 뒤에 다시 lombok AP가 돌면서 발생하는 것으로 보인다.
  • 이 둘을 함께 지정해서 APT 를 수행해야 에러가 나지 않는다.
"-processor",
  "com.mysema.query.apt.jpa.JPAAnnotationProcessor,org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor"

Gradle Annotation Process 예

http://alvinalexander.com/java/jwarehouse/hibernate/build.gradle.shtml 에 있는 것을 옮겼다.

Gradle 기반으로 정적 분석 도구 사용시에 여기서 자동 생성된 클래스는 정적 분석에서 예외처리해줘야 한다.(/Q[A-Z].*\.class/, /.*\_.class/) Java Static Analysis 를 참조한다.

ext.jpaMetamodelGeneratedDir = "$buildDir/생성된 메타 모델 클래스를 저장할 디렉토리"
 
configurations {
    jpaMetamodelGen {
        extendsFrom compile
    }
}
 
dependencies {
    jpaMetamodelGen "org.hibernate:hibernate-jpamodelgen:1.2.0.Final"
}
 
sourceSets {
    main {
        java {
            srcDir jpaMetamodelGeneratedDir
        }
    }
}
 
idea {
    module {
        sourceDirs += file(jpaMetamodelGeneratedDir)
    }
}
 
task generateJpaMetamodel(type: JavaCompile) {
 
    def targetDir = file(jpaMetamodelGeneratedDir)
    def compiledDestinationDir = "${buildDir}/tmp/apt-jpa"
    doFirst {
        // 항상 대상 디렉토리를 먼저 비우고 시작해야 한다.
        delete(targetDir)
        targetDir.mkdirs()
    }
 
    doLast {
        delete(compiledDestinationDir) // UP-TO-DATE 방지
    }
 
    // -proc:only 는 Annotation Processor로 소스 생성만 한다 컴파일은 하지 않음
    // -s 경로 는 생성된 소스가 들어갈 디렉토리를 뜻한다.
    classpath = configurations.jpaMetamodelGen
    source = sourceSets.main.java
    destinationDir = file(compiledDestinationDir)
    options.define(
        compilerArgs: [
            "-nowarn",
            "-proc:only",
            "-encoding", "UTF-8",
            "-s", targetDir.absolutePath,
            // processor 지정은 안해도 된다. 안하면 모든 어노테이션 프로세서 실행
            "-processor", "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor"         ]
    )
}
 
// 필요하면 compileJava가 generateJpaMetamodel 에 의존하도록 변경한다.

Lombok 사용시

Lombok 사용시 문제가 된다면 개인취향 JPA 사용기 - QueryDSL + Gradle + Lombok – Gemini Kim – Medium 참고. querydsl + lombok problem · Issue #59 · ewerk/gradle-plugins

task generateQueryDSL(type: JavaCompile, group: 'build') {
	source = sourceSets.main.java
	classpath = configurations.compile
	destinationDir = queryDslOutput
	options.compilerArgs = [
			"-proc:only",
                        /********************* 핵심 포인트! *********************/
			"-processor", 'com.querydsl.apt.jpa.JPAAnnotationProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor'
	]
}
compileJava.dependsOn(generateQueryDSL)
gradle/jpa_metamodel_generation.txt · 마지막으로 수정됨: 2018/08/23 17:41 저자 kwon37xi