ソフラボの技術ブログ

仕事で使ったプログラミング、サーバー周りで役に立つこと、Webサービス開発に必要な技術情報、モバイル情報を書いてます。わかりやすく見やすくをモットーにしています。

Domaのエンティティ等にLombokを使うと競合するので注意

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上ではエラーが出てないのになんで?と思ってググってみたら、次のツイートが目についた。


コンストラクタの自動生成で競合してるようです。
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クラスのアウトライン

f:id:shinsuke789:20141010121806p:plain

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クラスのアウトライン

f:id:shinsuke789:20141010091257j:plain

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();
}

原因

まだ特定はできてないですが、私の環境だけで起こる現象のようです。