Core JavaJava

Map an Empty String to Null Using MapStruct Example

1. Introduction

An empty string (“”) is the String object with an intentional blank value. Null is a literal used in Java to denote the absence of an object and is the default value for the reference type object. Null typically means “no value” or “unknown”. In many cases, these two should be treated differently. However, if an empty string does not carry any meaningful distinction, converting it to null helps reduce ambiguity. In this example, I will demonstrate MapStruct empty String null conversion.

2. Setup

In this step, I will create a Gradle project along with Lombok and MapStruct libraries.

build.gradle

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.4.5'
    id 'io.spring.dependency-management' version '1.1.7'
}
 
group = 'com.zheng.mapstruct.demo'
version = '0.0.1-SNAPSHOT'
 
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}
 
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}
 
repositories {
    mavenCentral()
}
 
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
     
    implementation 'org.mapstruct:mapstruct:1.5.5.Final'   
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
     
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
 
tasks.named('test') {
    useJUnitPlatform()
}

3. Java POJO

3.1 Source Class

In this step, I will create a Source.java that has two String fields: field1 and field2.

Source.java

01
02
03
04
05
06
07
08
09
10
11
12
13
package com.zheng.mapstruct.demo.data;
 
import lombok.Data;
import lombok.NoArgsConstructor;
 
@Data
@NoArgsConstructor
public class Source {
 
    private String field1;
    private String field2;
 
}

3.2 Target Class

In this step, I will create a Target.java that has two String fields: field1 and field2.

Target.java

01
02
03
04
05
06
07
08
09
10
11
12
package com.zheng.mapstruct.demo.data;
 
import lombok.Data;
import lombok.NoArgsConstructor;
 
@Data
@NoArgsConstructor
public class Target {
 
    private String field1;
    private String field2;
}

4. Mapstruct Empty String Null Mapper Interface

In this step, I will create several Mapper Interfaces that map the Source to Target and map empty String to null:

  • MapperWithCondition: map String to null based on the isNotEmpty condition. It applies to all String fields satisfying the condition.
  • MapperWithGlobalMethod: map String to null based on the default emptyStringToNull method. It applies to all String fields.
  • MapperWithExpression: map String to null based on the java(source.getField2() != null && !source.getField2().trim().isEmpty() ? source.getField2() : null) expression. It only applies to field2 annotated with @Mapping.
  • MapperWithQualifiedByName: map String to null based on the qualifiedByName="emptyToNull" attribute. It only applies to field2 annotated with @Mapping. The emptyToNull method is defined within the class.
  • MapperWithExternalQualifiedByName: map String to null based on the qualifiedByName="emptyStringToNull" attribute. It only applies to field2 annotated with @Mapping. The emptyStringToNull method is defined in StringTransformUtils.class.
  • MapperWithQualifiedBy: map String to null based on the qualifiedBy = EmptyStringToNull.class attribute. It only applies to field2 annotated with @Mapping.

4.1 Mapstruct Empty String Null via Default Method for All String

In this step, I will create a MapperWithGlobalMethod to map String to null based on the default emptyStringToNull method. It applies to all String fields.

MapperWithGlobalMethod.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
package com.zheng.mapstruct.demo.mapper;
 
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
 
import com.zheng.mapstruct.demo.data.Source;
import com.zheng.mapstruct.demo.data.Target;
 
@Mapper
public interface MapperWithGlobalMethod {
    MapperWithGlobalMethod INSTANCE = Mappers.getMapper(MapperWithGlobalMethod.class);
 
    default String emptyStringToNull(String value) {
        return (value == null || value.trim().isEmpty()) ? null : value;
    }
 
    Target map(Source source);
 
}
  • Line 13: the default method to map an empty string to null.

4.2 Mapstruct Empty String Null via @Condition Method for All String

In this step, I will create a MapperWithCondition to map String to null based on the default isNotEmpty condition method. It applies to all String fields.

MapperWithCondition.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
package com.zheng.mapstruct.demo.mapper;
 
import org.mapstruct.Condition;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
 
import com.zheng.mapstruct.demo.data.Source;
import com.zheng.mapstruct.demo.data.Target;
 
@Mapper
public interface MapperWithCondition {
    MapperWithCondition INSTANCE = Mappers.getMapper(MapperWithCondition.class);
 
    @Condition
    default boolean isNotEmpty(String value) {
        return value != null && !value.trim().isEmpty();
    }
 
    Target map(Source source);
 
}
  • Line 14: @Condition annotation is added.
  • Line 15: the default method to convert an empty string to null.

4.3 Mapstruct Empty String Null via Expression

In this step, I will create a MapperWithExpression to map String to null based on the @Mapping‘s expression attribute. It applies to the fields annotated with @Mapping fields.

MapperWithExpression.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
package com.zheng.mapstruct.demo.mapper;
 
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
 
import com.zheng.mapstruct.demo.data.Source;
import com.zheng.mapstruct.demo.data.Target;
 
@Mapper
public interface MapperWithExpression {
    MapperWithExpression INSTANCE = Mappers.getMapper(MapperWithExpression.class);
 
    @Mapping(target = "field2", expression = "java(source.getField2() != null && !source.getField2().trim().isEmpty() ? source.getField2() : null)")
    Target map(Source source);
 
}
  • Line 14: an expression is added to convert an empty string to null.

4.4 Mapstruct Empty String Null via QualifiedByName

In this step, I will create a MapperWithQualifiedByName to map String to null based on the static emptyToNull method annotated with @Named("emptyToNull"). It applies to the fields annotated with @Mapping.

MapperWithQualifiedByName.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.zheng.mapstruct.demo.mapper;
 
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;
 
import com.zheng.mapstruct.demo.data.Source;
import com.zheng.mapstruct.demo.data.Target;
 
@Mapper
public interface MapperWithQualifiedByName {
    MapperWithQualifiedByName INSTANCE = Mappers.getMapper(MapperWithQualifiedByName.class);
 
    @Named("emptyToNull")
    static String emptyToNull(String value) {
        return (value == null || value.trim().isEmpty()) ? null : value;
    }
 
    @Mapping(target = "field2", qualifiedByName = "emptyToNull")
    Target map(Source source);
 
}
  • Line 15: annotate with @Named("emptyToNull").
  • Line 16: a static method to convert an empty string to null.
  • Line 20: add the qualifiedByName attribute for the @Mapping.

4.5 Mapstruct Empty String Null via QualifiedByName Externally

In this step, I will create a MapperWithExternalQualifiedByName that maps String to null based on a static emptyStringToNull method annotated with @Named("emptyToNull") and defined externally in StringTransformUtils.class. It applies to the fields annotated with @Mapping.

MapperWithExternalQualifiedByName.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
package com.zheng.mapstruct.demo.mapper;
 
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
 
import com.zheng.mapstruct.demo.data.Source;
import com.zheng.mapstruct.demo.data.Target;
 
@Mapper(uses = StringTransformUtils.class)
public interface MapperWithExternalQualifiedByName {
    MapperWithExternalQualifiedByName INSTANCE = Mappers.getMapper(MapperWithExternalQualifiedByName.class);
 
    @Mapping(source = "field2", target = "field2", qualifiedByName = "emptyStringToNull")
    Target emptyToNullMapper(Source src);
 
    Target map(Source src);
 
}
  • Line 10: uses the StringTransformUtils class.
  • Line 14: set “emptyStringToNull” for the qualifiedByName attribute.

StringTransformUtils.java

01
02
03
04
05
06
07
08
09
10
11
package com.zheng.mapstruct.demo.mapper;
 
import org.mapstruct.Named;
 
@Named("emptyStringToNull")
public class StringTransformUtils {
    public static String emptyStringToNull(String val) {
        return (val == null || val.trim().isEmpty()) ? null : val;
    }
 
}
  • Line 5, annotated @Named for the emptyStringToNull.
  • Line 7: define a static method to convert an empty string to null.

4.6 Mapstruct Empty String Null via QualifiedBy

In this step, I will create a MapperWithQualifiedBy that maps String to null based on a default emptyStringToNull method annotated with customized @EmptyStringToNull. It applies to the fields annotated with @Mapping.

MapperWithQualifiedBy.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.zheng.mapstruct.demo.mapper;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
 
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Qualifier;
import org.mapstruct.factory.Mappers;
 
import com.zheng.mapstruct.demo.data.Source;
import com.zheng.mapstruct.demo.data.Target;
 
@Mapper
public interface MapperWithQualifiedBy {
    @Qualifier
    @java.lang.annotation.Target(ElementType.METHOD)
    @Retention(RetentionPolicy.CLASS)
    public @interface EmptyStringToNull {
    }
 
    MapperWithQualifiedBy INSTANCE = Mappers.getMapper(MapperWithQualifiedBy.class);
 
    @EmptyStringToNull
    default String emptyStringToNull(String s) {
        return s.isEmpty() ? null : s;
    }
 
    @Mapping(target = "field2", qualifiedBy = EmptyStringToNull.class)
    Target map(Source source);
 
}
  • Line 20: define a customized annotation.
  • Line 25, 26: define a default method to convert an empty string to null.
  • Line 30: add the qualifiedBy attribute to @Mapping.

5. Generated Mapper Implementation Class

5.1 MapperWithGlobalMethodImpl

In this step, I will view the generated mapper implementation class: MapperWithGlobalMethodImpl.

MapperWithGlobalMethodImpl.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.zheng.mapstruct.demo.mapper;
 
import com.zheng.mapstruct.demo.data.Source;
import com.zheng.mapstruct.demo.data.Target;
import javax.annotation.processing.Generated;
 
@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2025-05-02T21:28:44-0500",
    comments = "version: 1.5.5.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-8.13.jar, environment: Java 17 (Oracle Corporation)"
)
public class MapperWithGlobalMethodImpl implements MapperWithGlobalMethod {
 
    @Override
    public Target map(Source source) {
        if ( source == null ) {
            return null;
        }
 
        Target target = new Target();
 
        target.setField1( emptyStringToNull( source.getField1() ) );
        target.setField2( emptyStringToNull( source.getField2() ) );
 
        return target;
    }
}
  • Line 22, 23: Both field1 and field2 are mapped by emptyStringToNull.

5.2 MapperWithConditionImpl

In this step, I will view the generated mapper implementation class: MapperWithConditionImpl.

MapperWithConditionImpl.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.zheng.mapstruct.demo.mapper;
 
import com.zheng.mapstruct.demo.data.Source;
import com.zheng.mapstruct.demo.data.Target;
import javax.annotation.processing.Generated;
 
@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2025-05-02T21:28:44-0500",
    comments = "version: 1.5.5.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-8.13.jar, environment: Java 17 (Oracle Corporation)"
)
public class MapperWithConditionImpl implements MapperWithCondition {
 
    @Override
    public Target map(Source source) {
        if ( source == null ) {
            return null;
        }
 
        Target target = new Target();
 
        if ( isNotEmpty( source.getField1() ) ) {
            target.setField1( source.getField1() );
        }
        if ( isNotEmpty( source.getField2() ) ) {
            target.setField2( source.getField2() );
        }
 
        return target;
    }
}
  • Line 22, 25: an if isNotEmpty condition is checked.

5.3 MapperWithExpressionImpl

In this step, I will view the generated mapper implementation class: MapperWithExpressionImpl.

MapperWithExpressionImpl.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.zheng.mapstruct.demo.mapper;
 
import com.zheng.mapstruct.demo.data.Source;
import com.zheng.mapstruct.demo.data.Target;
import javax.annotation.processing.Generated;
 
@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2025-05-02T21:28:44-0500",
    comments = "version: 1.5.5.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-8.13.jar, environment: Java 17 (Oracle Corporation)"
)
public class MapperWithExpressionImpl implements MapperWithExpression {
 
    @Override
    public Target map(Source source) {
        if ( source == null ) {
            return null;
        }
 
        Target target = new Target();
 
        target.setField1( source.getField1() );
 
        target.setField2( source.getField2() != null && !source.getField2().trim().isEmpty() ? source.getField2() : null );
 
        return target;
    }
}
  • Line 24: the field2 setter applies the expression defined in @Mapping.

5.4 MapperWithQualifiedByNameImpl

In this step, I will view the generated mapper implementation class: MapperWithQualifiedByNameImpl.

MapperWithQualifiedByNameImpl.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.zheng.mapstruct.demo.mapper;
 
import com.zheng.mapstruct.demo.data.Source;
import com.zheng.mapstruct.demo.data.Target;
import javax.annotation.processing.Generated;
 
@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2025-05-02T21:28:44-0500",
    comments = "version: 1.5.5.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-8.13.jar, environment: Java 17 (Oracle Corporation)"
)
public class MapperWithQualifiedByNameImpl implements MapperWithQualifiedByName {
 
    @Override
    public Target map(Source source) {
        if ( source == null ) {
            return null;
        }
 
        Target target = new Target();
 
        target.setField2( MapperWithQualifiedByName.emptyToNull( source.getField2() ) );
        target.setField1( source.getField1() );
 
        return target;
    }
}
  • Line 22: the field2 setter applies the static MapperWithQualifiedByName.emptyToNull.

5.5 MapperWithExternalQualifiedByNameImpl

In this step, I will view the generated mapper implementation class: MapperWithExternalQualifiedByNameImpl.

MapperWithExternalQualifiedByNameImpl.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.zheng.mapstruct.demo.mapper;
 
import com.zheng.mapstruct.demo.data.Source;
import com.zheng.mapstruct.demo.data.Target;
import javax.annotation.processing.Generated;
 
@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2025-05-02T21:28:44-0500",
    comments = "version: 1.5.5.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-8.13.jar, environment: Java 17 (Oracle Corporation)"
)
public class MapperWithExternalQualifiedByNameImpl implements MapperWithExternalQualifiedByName {
 
    @Override
    public Target emptyToNullMapper(Source src) {
        if ( src == null ) {
            return null;
        }
 
        Target target = new Target();
 
        target.setField2( StringTransformUtils.emptyStringToNull( src.getField2() ) );
        target.setField1( src.getField1() );
 
        return target;
    }
 
    @Override
    public Target map(Source src) {
        if ( src == null ) {
            return null;
        }
 
        Target target = new Target();
 
        target.setField1( src.getField1() );
        target.setField2( src.getField2() );
 
        return target;
    }
}
  • Line 22: the field2 setter uses the static StringTransformUtils.emptyStringToNull.

5.6 MapperWithQualifiedByImpl

In this step, I will view the generated mapper implementation class: MapperWithQualifiedByImpl.

MapperWithQualifiedByImpl.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.zheng.mapstruct.demo.mapper;
 
import com.zheng.mapstruct.demo.data.Source;
import com.zheng.mapstruct.demo.data.Target;
import javax.annotation.processing.Generated;
 
@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2025-05-02T21:28:44-0500",
    comments = "version: 1.5.5.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-8.13.jar, environment: Java 17 (Oracle Corporation)"
)
public class MapperWithQualifiedByImpl implements MapperWithQualifiedBy {
 
    @Override
    public Target map(Source source) {
        if ( source == null ) {
            return null;
        }
 
        Target target = new Target();
 
        target.setField2( emptyStringToNull( source.getField2() ) );
        target.setField1( source.getField1() );
 
        return target;
    }
}
  • Line 22: the field2 setter applies via the emptyStringToNull.

6. Test Mapstruct Empty String Null

6.1 TestBase

In this step, I will create TestBase.java that defines the source and target variables and setupFields method to prepare the test data.

TestBase.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.zheng.mapstruct.demo.mapper;
 
import com.zheng.mapstruct.demo.data.Source;
import com.zheng.mapstruct.demo.data.Target;
 
public class TestBase {
 
    protected Source source;
 
    protected Target target;
 
    public TestBase() {
        super();
    }
 
    protected void setupFields(String field1, String field2) {
        source = new Source();
        source.setField1(field1);
        source.setField2(field2);
    }
 
}

6.2 MapperWithGlobalMethodTest

In this step, I will create a MapperWithGlobalMethodTest.java that verifies all the empty string fields are converted to null.

MapperWithGlobalMethodTest.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.zheng.mapstruct.demo.mapper;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
 
import org.junit.jupiter.api.Test;
 
class MapperWithGlobalMethodTest extends TestBase {
 
    private MapperWithGlobalMethod testClass = MapperWithGlobalMethod.INSTANCE;
 
    @Test
    void test_Field2_emptyToNull() {
        setupFields("", "");
 
        target = testClass.map(source);
 
        assertNull(target.getField1());
        assertNull(target.getField2());
    }
 
    @Test
    void test_Field1_still_empty() {
        setupFields("T", "");
 
        target = testClass.map(source);
 
        assertEquals("T", target.getField1());
        assertNull(target.getField2());
    }
}

6.3 MapperWithConditionTest

In this step, I will create a MapperWithConditionTest.java that verifies all the empty string fields are converted to null.

MapperWithConditionTest.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.zheng.mapstruct.demo.mapper;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
 
import org.junit.jupiter.api.Test;
 
class MapperWithConditionTest extends TestBase {
 
    private MapperWithCondition testClass = MapperWithCondition.INSTANCE;
 
    @Test
    void test_emptyToNull() {
        setupFields("", "");
 
        target = testClass.map(source);
 
        assertNull(target.getField1());
        assertNull(target.getField2());
    }
 
    @Test
    void test_nonEmpty_is_mapped() {
        setupFields("T", "");
 
        target = testClass.map(source);
 
        assertEquals("T", target.getField1());
        assertNull(target.getField2());
    }
}

6.4 MapperWithExpressionTest

In this step, I will create a MapperWithExpressionTest.java that verifies an empty string at field2 is converted to null.

MapperWithExpressionTest.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.zheng.mapstruct.demo.mapper;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
 
import org.junit.jupiter.api.Test;
 
class MapperWithExpressionTest  extends TestBase {
 
    private MapperWithExpression testClass = MapperWithExpression.INSTANCE;
 
    @Test
    void test_Field2_emptyToNull() {
        setupFields("T", "");
         
        target = testClass.map(source);
         
        assertEquals("T", target.getField1());
        assertNull(target.getField2());
    }
     
    @Test
    void test_Field1_remain_empty() {
        setupFields("", "");
         
        target = testClass.map(source);     
         
        assertEquals("", target.getField1());
        assertNull(target.getField2());
    }
}

6.5 MapperWithQualifiedByName

In this step, I will create a MapperWithQualifiedByName.java that verifies an empty string at field2 is converted to null.

MapperWithQualifiedByName.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.zheng.mapstruct.demo.mapper;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
 
import org.junit.jupiter.api.Test;
 
class MapperWithQualifiedByNameTest extends TestBase {
 
    private MapperWithQualifiedByName testClass = MapperWithQualifiedByName.INSTANCE;
 
    @Test
    void test_Field2_emptyToNull() {
        setupFields("", "");
         
        target = testClass.map(source);
         
        assertEquals("", target.getField1());
        assertNull(target.getField2());
    }
     
    @Test
    void test_Field1_still_empty() {
        setupFields("T", "");
         
        target = testClass.map(source);     
         
        assertEquals("T", target.getField1());
        assertNull(target.getField2());
    }
}

6.6 MapperWithExternalQualifiedByNameTest

In this step, I will create a MapperWithExternalQualifiedByNameTest.java that verifies an empty string at field2 is converted to null.

MapperWithExternalQualifiedByNameTest.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.zheng.mapstruct.demo.mapper;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
 
import org.junit.jupiter.api.Test;
 
class MapperWithExternalQualifiedByNameTest extends TestBase {
 
    private MapperWithExternalQualifiedByName testClass = MapperWithExternalQualifiedByName.INSTANCE;
 
    @Test
    void test_Field2_emptyToNull() {
        setupFields("", "");
 
        target = testClass.emptyToNullMapper(source);
 
        assertEquals("", target.getField1());
        assertNull(target.getField2());
    }
 
    @Test
    void test_normalmap_remain_empty() {
        setupFields("T", "");
 
        target = testClass.map(source);
 
        assertEquals("T", target.getField1());
        assertEquals("", target.getField2());
    }
 
}

6.7 MapperWithQualifiedByTest

In this step, I will create a MapperWithQualifiedByTest.java that verifies an empty string at field2 is converted to null.

MapperWithQualifiedByTest.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.zheng.mapstruct.demo.mapper;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
 
import org.junit.jupiter.api.Test;
 
class MapperWithQualifiedByTest extends TestBase {
 
    private MapperWithQualifiedBy testClass = MapperWithQualifiedBy.INSTANCE;
 
    @Test
    void test_Field2_emptyToNull() {
        setupFields("", "");
         
        target = testClass.map(source);
         
        assertEquals("", target.getField1());
        assertNull(target.getField2());
    }
     
    @Test
    void test_Field1_still_empty() {
        setupFields("T", "");
         
        target = testClass.map(source);     
         
        assertEquals("T", target.getField1());
        assertNull(target.getField2());
    }
}

Run the Junit tests and capture the test results

mapstruct empty string null
Figure 1. Test Results

7. Conclusion

In this example, I demonstrated several ways to convert an empty string to null with MapStruct. The global default method is the simplest way. I outlined the difference in the following table.

Global Default@ConditionexpressionqualifiedByNamequalifiedBy
ExampleMapperWithGlobalMethodMapperWithConditionMapperWithExpressionMapperWithExternalQualifiedByName, MapperWithQualifiedByNameMapperWithQualifiedBy
Apply to All String fields?YesYesNoNoNo
Descriptionapplies to every String→String mapping automatically.the empty value is skipped during the mapping.@Named is applied to the emptyToNull methoda customized qualifier annotation EmptyStringToNull is defined
Details@Condition is applied to a default methodexpression is one of the @Mapping attributesqualifiedByName is one of the @Mapping attributesqualifiedBy is one of the @Mapping attributes
When to use?many String fieldsUpdating existing objects, preserving old valuesOne‑off, very custom logicFew fields & you want clarityFew fields & you want clarity

8. Download

This was an example of a Gradle project that used Mapstruct to convert empty strings to nulls.

Download
You can download the full source code of this example here: Map an Empty String to Null Using MapStruct Example

Mary Zheng

Mary graduated from the Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She worked as a lead Software Engineer where she led and worked with others to design, implement, and monitor the software solution.
Subscribe
Notify of
guest


This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button