Mastruct with Quarkus: How to inject

2,751 views
Skip to first unread message

Brand Bintley

unread,
Jun 4, 2021, 9:42:44 AM6/4/21
to Quarkus Development mailing list
I am trying to run a basic example that uses Mastructs as per https://mapstruct.org/news/2019-12-06-mapstruct-and-quarkus/.

In the resource, the author uses @Inject annotation to inject the mapper in the resource class. That causes an exception:

UnsatisfiedResolutionException: Unsatisfied dependency for type org.mapstruct.example.quarkus.PersonMapper and qualifiers [@Default]


However, if I remove the @Inject annotation as per this other article, no injection happens at all: https://stephennimmo.com/building-a-customer-api-using-quarkus-from-the-ground-up/. The mapper remains null.


What am I missing?


Thanks.


Paul Carter-Brown

unread,
Jun 4, 2021, 9:48:18 AM6/4/21
to brand....@gmail.com, Quarkus Development mailing list

Make sure you have @Mapper(componentModel = "CDI") on your mapper interface.

You can then happily inject it with @Inject


--
You received this message because you are subscribed to the Google Groups "Quarkus Development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quarkus-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CABEjM6S-4hKndz5Td2pwNH51amsu9M3N8OofP3mM99BxPU_bbg%40mail.gmail.com.

Brand Bintley

unread,
Jun 4, 2021, 12:22:18 PM6/4/21
to Paul Carter-Brown, Quarkus Development mailing list
Somehow this doesn't work for me. Here are my classes:



package org.mapstruct.example.quarkus;


public class Person {

private String firstname;

private String lastname;

// all-args constructor, getters, setters

}



package org.mapstruct.example.quarkus;

public class PersonDto {

  private String firstname;

  private String surname;  

  // getters, setters

}



=====

package org.mapstruct.example.quarkus;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper(componentModel = "CDI")
public interface PersonMapper {
    @Mapping(target = "surname", source = "lastname")
    PersonDto toResource(Person person);
}
=========
package org.mapstruct.example.quarkus;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/person")
public class PersonResource {
 
  @Inject
  PersonService personService;
 
  @Inject
  PersonMapper personMapper;
 
  @GET
  @Produces(MediaType.APPLICATION_JSON)
  public PersonDto loadPerson() {
    return personMapper.toResource( personService.loadPerson() );
  }
}

=====

package org.mapstruct.example.quarkus;


import javax.enterprise.context.ApplicationScoped;


@ApplicationScoped

public class PersonService {

  public Person loadPerson() {

    return new Person("Bob", "Miller");

  }

}

Paul Carter-Brown

unread,
Jun 4, 2021, 12:30:19 PM6/4/21
to Brand Bintley, Quarkus Development mailing list
Do you have the mapstruct plugin as part of your build so it can do its source generation?

Verify it's running when you build

KimJohn Quinn

unread,
Jun 5, 2021, 8:32:54 AM6/5/21
to Quarkus Development mailing list
We do this and it works:

POM:

----------- Plugins

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <parameters>true</parameters>
        <source>11</source>
        <target>11</target>
        <annotationProcessorPaths>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </path>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok-mapstruct-binding</artifactId>
                <version>0.1.0</version>
            </path>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>${mapstruct.version}</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

----------- Dependencies

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok-mapstruct-binding</artifactId>
    <version>0.1.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>${mapstruct.version}</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>${mapstruct.version}</version>
    <scope>provided</scope>
</dependency>

----------- Mapper Config

@MapperConfig(
    componentModel = "cdi",
    implementationName = "<CLASS_NAME>Impl",
    unmappedSourcePolicy = IGNORE,
    unmappedTargetPolicy = WARN,
    mappingInheritanceStrategy = AUTO_INHERIT_ALL_FROM_CONFIG,
    nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public interface Mappable
{
}

----------- Mapper

@Mapper(config = Mappable.class)
public abstract class ProjectMapper 
{
Reply all
Reply to author
Forward
0 new messages