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
: mapString
tonull
based on theisNotEmpty
condition. It applies to allString
fields satisfying the condition.MapperWithGlobalMethod
: mapString
tonull
based on thedefault
emptyStringToNull
method. It applies to allString
fields.MapperWithExpression
: mapString
tonull
based on thejava(source.getField2() != null && !source.getField2().trim().isEmpty() ? source.getField2() : null)
expression. It only applies tofield2
annotated with@Mapping
.MapperWithQualifiedByName
: mapString
tonull
based on thequalifiedByName="emptyToNull"
attribute. It only applies tofield2
annotated with@Mapping
. TheemptyToNull
method is defined within the class.MapperWithExternalQualifiedByName
: mapString
tonull
based on thequalifiedByName="emptyStringToNull"
attribute. It only applies tofield2
annotated with@Mapping
. TheemptyStringToNull
method is defined inStringTransformUtils.class
.MapperWithQualifiedBy
: mapString
tonull
based on thequalifiedBy = EmptyStringToNull.class
attribute. It only applies tofield2
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 tonull
.
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 tonull
.
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 tonull
.
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 tonull
. - 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 thequalifiedByName
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 theemptyStringToNull
. - Line 7: define a
static
method to convert an empty string tonull
.
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 tonull
. - 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
andfield2
are mapped byemptyStringToNull
.
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 theexpression
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 thestatic
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 thestatic 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 theemptyStringToNull
.
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
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 | @Condition | expression | qualifiedByName | qualifiedBy | |
Example | MapperWithGlobalMethod | MapperWithCondition | MapperWithExpression | MapperWithExternalQualifiedByName, MapperWithQualifiedByName | MapperWithQualifiedBy |
Apply to All String fields? | Yes | Yes | No | No | No |
Description | applies to every String→String mapping automatically. | the empty value is skipped during the mapping. | @Named is applied to the emptyToNull method | a customized qualifier annotation EmptyStringToNull is defined | |
Details | @Condition is applied to a default method | expression is one of the @Mapping attributes | qualifiedByName is one of the @Mapping attributes | qualifiedBy is one of the @Mapping attributes | |
When to use? | many String fields | Updating existing objects, preserving old values | One‑off, very custom logic | Few fields & you want clarity | Few fields & you want clarity |
8. Download
This was an example of a Gradle project that used Mapstruct
to convert empty strings to null
s.
You can download the full source code of this example here: Map an Empty String to Null Using MapStruct Example