SpringBoot+Domaの検証を行っていて、WARファイルでも作ってみるかとGradleからビルドしたら、何回やってもコンパイルエラーになって困った。
いきなりミュータブルとか言われてもよく分からない。
エラー: [DOMA4124] ミュータブルなエンティティクラスは非privateな引数なしのコンストラクタを持たねばなりません。イミュータブルにするには@Entityのimmutable要素にtrueを設定してください。 public class Emp { ^ エラー1個 :compileJava FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':compileJava'. > Compilation failed; see the compiler error output for details. * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more l og output. BUILD FAILED
Eclipse上ではエラーが出てないのになんで?と思ってググってみたら、次のツイートが目についた。
lombokとdomaは相性が良くなさそうな予感がするなー。domaていうかapt。どうなんだろー。
— Mitsuyuki Shiiba (@bufferings) March 12, 2014コンストラクタの自動生成で競合してるようです。
DomaのエンティティクラスにあるLombokの@Dataアノテーションを削除したらビルドできました。
基本的にDomaのエンティティはpublicフィールド対応してるのでLombokは不要です。
SpringBootを検証しているうちにいつのまにかエンティティに@Dataを付与してしまってたみたいです…。
# 2014/10/09 追記
ソース
環境
| Eclipse | 4.3 |
|---|
Dept.java
package demo.entity; import lombok.Data; import org.seasar.doma.Entity; import org.seasar.doma.Id; import org.seasar.doma.jdbc.entity.NamingType; @Data @Entity(naming = NamingType.SNAKE_LOWER_CASE) public class Dept { @Id public String deptNo; public String deptNm; }
build.gradle
buildscript {
ext {
springBootVersion = '1.1.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'war'
/*
jar {
baseName = 'demo'
version = '1.0'
}*/
war {
baseName = 'demo'
version = '1.0'
}
sourceCompatibility = 1.7
targetCompatibility = 1.7
// for Doma
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
processResources.destinationDir = compileJava.destinationDir
compileJava.dependsOn processResources
def aptGeneratePath = '.apt_generated'
compileJava.options.compilerArgs = ['-s', aptGeneratePath]
new File(aptGeneratePath).mkdirs()
repositories {
mavenCentral()
maven {url 'http://maven.seasar.org/maven2'}
}
configurations {
providedRuntime
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-aop")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.hibernate:hibernate-validator")
compile("org.springframework:spring-jdbc")
compile("org.seasar.doma:doma:1.+")
compile("org.seasar.container:s2-tiger:2.4.47")
compile files("C:/app/lib/jdbc/ojdbc7.jar")
compile files("C:/app/lib/lombok/lombok-1.14.8.jar")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
//testCompile("org.springframework.boot:spring-boot-starter-test")
}
eclipse {
classpath {
containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7'
}
}
task wrapper(type: Wrapper) {
gradleVersion = '1.12'
}
# 2014/10/10 追記
クラスファイル
「javap クラスファイル名」の結果
@Dataがない状態
Deptクラスのアウトライン

Dept.class
Compiled from "Dept.java" public class demo.entity.Dept { public java.lang.String deptNo; public java.lang.String deptNm; public demo.entity.Dept(); }
_Dept.class
Compiled from "_Dept.java" public final class demo.entity._Dept extends org.seasar.doma.jdbc.entity.AbstractEntityType<demo.entity.Dept> { public final org.seasar.doma.jdbc.entity.BasicPropertyType<java.lang.Object, demo.entity.Dept, java.lang.String, java.lang.Object> $deptNm; public final org.seasar.doma.jdbc.entity.AssignedIdPropertyType<java.lang.Object, demo.entity.Dept, java.lang.String, java.lang.Object> $deptNo; static {}; public org.seasar.doma.jdbc.entity.NamingType getNamingType(); public boolean isImmutable(); public java.lang.String getName(); public java.lang.String getCatalogName(); public java.lang.String getSchemaName(); public java.lang.String getTableName(); public java.lang.String getQualifiedTableName(); public void preInsert(demo.entity.Dept, org.seasar.doma.jdbc.entity.PreInsertContext<demo.entity.Dept>); public void preUpdate(demo.entity.Dept, org.seasar.doma.jdbc.entity.PreUpdateContext<demo.entity.Dept>); public void preDelete(demo.entity.Dept, org.seasar.doma.jdbc.entity.PreDeleteContext<demo.entity.Dept>); public void postInsert(demo.entity.Dept, org.seasar.doma.jdbc.entity.PostInsertContext<demo.entity.Dept>); public void postUpdate(demo.entity.Dept, org.seasar.doma.jdbc.entity.PostUpdateContext<demo.entity.Dept>); public void postDelete(demo.entity.Dept, org.seasar.doma.jdbc.entity.PostDeleteContext<demo.entity.Dept>); public java.util.List<org.seasar.doma.jdbc.entity.EntityPropertyType<demo.entity.Dept, ?>> getEntityPropertyTypes(); public org.seasar.doma.jdbc.entity.EntityPropertyType<demo.entity.Dept, ?> getEntityPropertyType(java.lang.String); public java.util.List<org.seasar.doma.jdbc.entity.EntityPropertyType<demo.entity.Dept, ?>> getIdPropertyTypes(); public org.seasar.doma.jdbc.entity.GeneratedIdPropertyType<java.lang.Object, demo.entity.Dept, ?, ?> getGeneratedIdPropertyType(); public org.seasar.doma.jdbc.entity.VersionPropertyType<java.lang.Object, demo.entity.Dept, ?, ?> getVersionPropertyType(); public demo.entity.Dept newEntity(); public demo.entity.Dept newEntity(java.util.Map<java.lang.String, java.lang.Object>); public java.lang.Class<demo.entity.Dept> getEntityClass(); public demo.entity.Dept getOriginalStates(demo.entity.Dept); public void saveCurrentStates(demo.entity.Dept); public static demo.entity._Dept getSingletonInternal(); public static demo.entity._Dept newInstance(); public void postDelete(java.lang.Object, org.seasar.doma.jdbc.entity.PostDeleteContext); public void preInsert(java.lang.Object, org.seasar.doma.jdbc.entity.PreInsertContext); public void postUpdate(java.lang.Object, org.seasar.doma.jdbc.entity.PostUpdateContext); public void saveCurrentStates(java.lang.Object); public void preDelete(java.lang.Object, org.seasar.doma.jdbc.entity.PreDeleteContext); public void postInsert(java.lang.Object, org.seasar.doma.jdbc.entity.PostInsertContext); public java.lang.Object getOriginalStates(java.lang.Object); public java.lang.Object newEntity(java.util.Map); public java.lang.Object newEntity(); public void preUpdate(java.lang.Object, org.seasar.doma.jdbc.entity.PreUpdateContext); }
@Dataを付与した状態
Deptクラスのアウトライン

Dept.class
Compiled from "Dept.java" public class demo.entity.Dept { public java.lang.String deptNo; public java.lang.String deptNm; public java.lang.String getDeptNo(); public java.lang.String getDeptNm(); public void setDeptNo(java.lang.String); public void setDeptNm(java.lang.String); public boolean equals(java.lang.Object); protected boolean canEqual(java.lang.Object); public int hashCode(); public java.lang.String toString(); public demo.entity.Dept(); }
_Dept.class
Compiled from "_Dept.java" public final class demo.entity._Dept extends org.seasar.doma.jdbc.entity.AbstractEntityType<demo.entity.Dept> { public final org.seasar.doma.jdbc.entity.BasicPropertyType<java.lang.Object, demo.entity.Dept, java.lang.String, java.lang.Object> $deptNm; public final org.seasar.doma.jdbc.entity.AssignedIdPropertyType<java.lang.Object, demo.entity.Dept, java.lang.String, java.lang.Object> $deptNo; static {}; public org.seasar.doma.jdbc.entity.NamingType getNamingType(); public boolean isImmutable(); public java.lang.String getName(); public java.lang.String getCatalogName(); public java.lang.String getSchemaName(); public java.lang.String getTableName(); public java.lang.String getQualifiedTableName(); public void preInsert(demo.entity.Dept, org.seasar.doma.jdbc.entity.PreInsertContext<demo.entity.Dept>); public void preUpdate(demo.entity.Dept, org.seasar.doma.jdbc.entity.PreUpdateContext<demo.entity.Dept>); public void preDelete(demo.entity.Dept, org.seasar.doma.jdbc.entity.PreDeleteContext<demo.entity.Dept>); public void postInsert(demo.entity.Dept, org.seasar.doma.jdbc.entity.PostInsertContext<demo.entity.Dept>); public void postUpdate(demo.entity.Dept, org.seasar.doma.jdbc.entity.PostUpdateContext<demo.entity.Dept>); public void postDelete(demo.entity.Dept, org.seasar.doma.jdbc.entity.PostDeleteContext<demo.entity.Dept>); public java.util.List<org.seasar.doma.jdbc.entity.EntityPropertyType<demo.entity.Dept, ?>> getEntityPropertyTypes(); public org.seasar.doma.jdbc.entity.EntityPropertyType<demo.entity.Dept, ?> getEntityPropertyType(java.lang.String); public java.util.List<org.seasar.doma.jdbc.entity.EntityPropertyType<demo.entity.Dept, ?>> getIdPropertyTypes(); public org.seasar.doma.jdbc.entity.GeneratedIdPropertyType<java.lang.Object, demo.entity.Dept, ?, ?> getGeneratedIdPropertyType(); public org.seasar.doma.jdbc.entity.VersionPropertyType<java.lang.Object, demo.entity.Dept, ?, ?> getVersionPropertyType(); public demo.entity.Dept newEntity(); public demo.entity.Dept newEntity(java.util.Map<java.lang.String, java.lang.Object>); public java.lang.Class<demo.entity.Dept> getEntityClass(); public demo.entity.Dept getOriginalStates(demo.entity.Dept); public void saveCurrentStates(demo.entity.Dept); public static demo.entity._Dept getSingletonInternal(); public static demo.entity._Dept newInstance(); public void postDelete(java.lang.Object, org.seasar.doma.jdbc.entity.PostDeleteContext); public void preInsert(java.lang.Object, org.seasar.doma.jdbc.entity.PreInsertContext); public void postUpdate(java.lang.Object, org.seasar.doma.jdbc.entity.PostUpdateContext); public void saveCurrentStates(java.lang.Object); public void preDelete(java.lang.Object, org.seasar.doma.jdbc.entity.PreDeleteContext); public void postInsert(java.lang.Object, org.seasar.doma.jdbc.entity.PostInsertContext); public java.lang.Object getOriginalStates(java.lang.Object); public java.lang.Object newEntity(java.util.Map); public java.lang.Object newEntity(); public void preUpdate(java.lang.Object, org.seasar.doma.jdbc.entity.PreUpdateContext); }
# 2014/10/14 追記
@Dataのみ付与、Gradleでコンパイル
Dept.class
Compiled from "Dept.java" public class demo.form.Dept { public java.lang.String deptNo; public java.lang.String deptNm; public demo.form.Dept(); public java.lang.String getDeptNo(); public java.lang.String getDeptNm(); public void setDeptNo(java.lang.String); public void setDeptNm(java.lang.String); public boolean equals(java.lang.Object); protected boolean canEqual(java.lang.Object); public int hashCode(); public java.lang.String toString(); }
原因
まだ特定はできてないですが、私の環境だけで起こる現象のようです。