web-dev-qa-db-ja.com

MapStructの実装がSpringBootWebアプリケーションで機能しない

私はSpringBootと MapStruct Toolの初心者です。

以前は、プロジェクト(これらのテクノロジーを使用して他のチームによって作成された)は開始されていません。次に、マッパー抽象クラスにいくつかの変更を加えましたが、アプリケーションの起動時にマッパーオブジェクトがnullとして表示されるようになりました。

マッパー抽象クラス:

@Mapper(componentModel = "spring")
public abstract class UserAndEmployeeMapper {

    public UserAndEmployeeMapper INSTANCE = Mappers.getMapper( UserAndEmployeeMapper.class );

    @Mapping(source = "username", target = "name")
    @Mapping(source = "ssn", target = "ssn", defaultValue = "xxxxxx" )
    @Mapping(target = "salary", constant = "34.67")
    @Mapping(target = "dob", dateFormat = "dd/MM/yyyy", constant = "10/12/2002")
    public abstract Employee mapToEmployee(User user);

    public abstract List<Employee> mapToEmployee(List<User> users);

    @Mapping(source = "name", target = "username")
    public abstract User mapToUser(Employee employee);

    public abstract List<User> mapToUser(List<Employee> employees);

}

LoginServiceImplクラス

@Service("loginService")
public class LoginServiceImpl implements LoginService{

    private static final AtomicLong counter = new AtomicLong();

    @Autowired
    private EmployeeDao employeeDao;

    private UserAndEmployeeMapper userAndEmployeeMapper;
...

}

pom.xml

<build>
        <plugins>
            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${mapstruct.jdk8.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
</build>

LoginServiceImplに@Autowiredを追加した後、アプリケーションが起動せず、次のエラーログが表示されます

***************************
APPLICATION FAILED TO START
***************************

Description:

Field userAndEmployeeMapper in org.service.impl.LoginServiceImpl required a bean of type 'org.mapper.UserAndEmployeeMapper' that could not be found.


Action:

Consider defining a bean of type 'org.mapper.UserAndEmployeeMapper' in your configuration.

助言がありますか ?

3
Ankit

インターフェイスとして抽象クラスを作成することは私のために働きました。

public interface UserAndEmployeeMapper {
1
Ankit

まず、public UserAndEmployeeMapper INSTANCE = Mappers.getMapper( UserAndEmployeeMapper.class );はデフォルトのコンポーネントモデルでのみ使用する必要があります。そうしないと、UserAndEmployeeMapperが正しく初期化されないリスクがあります。

UserAndEmployeeMapperLoginServiceImplには@Autowiredの注釈を付ける必要があります。注釈を付けると、Springで挿入できません。そのため、nullになります。

パッケージの構造がわかりません。パッケージ内のSpringBootアプリケーションクラスがorgの場合、UserAndEmployeeMapperImplを取得します。それ以外の場合は、スプリング構成がUserAndEmployeeMapperImplを取得することを確認してください。

上記のすべてが正しくセットアップされていて、IDEを介してアプリケーションを起動している場合は、target/generated-sourcesまたはGradleの代替がソースの一部であり、ピックアップされていることを確認してください。 IDEサポート を調べて、IDEの注釈プロセッサ検出が正しく設定されていることを確認します。たとえば、IntelliJは現在の設定でMapStruct注釈プロセッサを呼び出さず、取得しません。 MavenコンパイラからのannotationProcessorPaths

3
Filip

springfox-swagger2依存関係は、古いバージョンのmapstructを除外し、pom.xmlに特定のバージョンのmapstruct依存関係を追加した後、ソースの生成を開始しました。

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
<exclusions>
 <exclusion>
 <groupId>org.mapstruct</groupId>
  <artifactId>mapstruct</artifactId>
 </exclusion>
</exclusions>

以下にマップ構造体の依存関係を追加

<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.0.Beta1</version>
2
skk

すべてのマッパークラスをSpringBeanとして認定するには、次のcompilerArgsをmaven-compiler-pluginに追加します。

<compilerArgs>
<arg>-Amapstruct.suppressGeneratorTimestamp=true</arg>
<arg>-Amapstruct.defaultComponentModel=spring</arg>
</compilerArgs> 

maven-processor-pluginを使用している場合は、次のオプションを追加します

<options>                       
<mapstruct.suppressGeneratorTimestamp>
true
</mapstruct.suppressGeneratorTimestamp>                      
<mapstruct.defaultComponentModel>
spring
</mapstruct.defaultComponentModel>
</options>
2
Minnow

私もこの問題に遭遇し、マッパーを抽象クラスからインターフェースに変更してもうまくいきませんでした。

私は終わりました:

  • マッパーインターフェイスからINSTANCEプロパティを削除する
  • インターフェイスを実装するクラスの作成、mappesメソッドの実装
  • このクラスのインスタンスを、マッパーを必要とするクラスの@Autowiredプロパティとして追加し、代わりにそれを呼び出します。

WebAppMapper.Java

    @Mapper(componentModel = "spring")
    public interface WebAppMapper {
        CatalogData createCatalogRequestToData(CreateCatalogRequest createCatalogRequest);
    }

WebAppMapperImpl.Java

@Component
public class WebAppMapperImpl implements WebAppMapper {
    @Override
    public CatalogData createCatalogRequestToData(CreateCatalogRequest createCatalogRequest) {
        CatalogData catalogData = new CatalogData();
        catalogData.setId(createCatalogRequest.getId());
        catalogData.setName(createCatalogRequest.getName());
        return catalogData;
    }
}

CatalogController.Java

@Autowired
WebAppMapper webAppMapper;

webAppMapper.createCatalogRequestToData(createCatalogRequest);

これは私のために働いた。

2
Chris Neve

私の場合、エラーは不完全なbuild.gradleが原因であると思います。

dependencies {
    compile group: 'org.mapstruct', name: 'mapstruct-processor', version: '1.2.0.Final'
}

apply plugin: 'net.ltgt.apt'

dependencies {
    compile group: 'org.mapstruct', name: 'mapstruct-processor', version: '1.2.0.Final'
    compile group: 'org.mapstruct', name: 'mapstruct-jdk8', version: '1.2.0.Final'
    apt 'org.mapstruct:mapstruct-processor:1.2.0.Final'
}


buildscript {
    repositories {
        mavenCentral()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath("net.ltgt.gradle:gradle-apt-plugin:0.9")
    }
}

ドキュメントで説明されているように、build.gradleが正しく構成されていることを確認してください

0
Chris Neve