Check empty Strings while mapping to LocalDateTime

4,211 views
Skip to first unread message

karl....@googlemail.com

unread,
Mar 2, 2017, 5:25:47 AM3/2/17
to mapstruct-users
Hi,

i am really impressed by mapstruct but i am facing a pretty simple mapping problem and dont know how to solve it. I hope you can help me.
I am working with Java 8 and MapStruct 1.1.0.Final

Here is my mapping from String to LocalDateTime:

@Mapping(target = "localDateTime", source = "dateString", dateFormat = "yyyy-MM-dd:HH:mm")
Target toTarget(Source src);



Unfortunately the source dateString can be an empty string and i dont know how to force mapstruct to not only check for null but for empty string either.


I hope you have a good hint for me.

Gunnar Morling

unread,
Mar 2, 2017, 5:57:22 AM3/2/17
to karl....@googlemail.com, mapstruct-users
Hi Karl,

It'd probably make sense to have some kind of global option for
controlling how to deal with empty strings.

But for the time being you could try it like this:

public interface MyMapper {

@Mapping(
target = "localDateTime",
expression = "java(emptyToNull(src.getDateString()))",
dateFormat = "yyyy-MM-dd:HH:mm"
)
Target toTarget(Source src);

default String emptyToNull(String s) {
return s == null || s.isEmpty() ? null : s;
}
}

I.e. feed the input property through some property which converts
empty strings to null before applying the mapping.

--Gunnar



2017-03-02 11:25 GMT+01:00 karl.w.roth via mapstruct-users
<mapstru...@googlegroups.com>:
> --
> You received this message because you are subscribed to the Google Groups
> "mapstruct-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mapstruct-use...@googlegroups.com.
> To post to this group, send email to mapstru...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

karl....@googlemail.com

unread,
Mar 2, 2017, 7:01:36 AM3/2/17
to mapstruct-users
Hi Gunnar,

thanks for the reply.
Your suggestion does not compile:
Here is my code:
@Mapper
public interface SourceTargetMapper {

   
SourceTargetMapper INSTANCE = Mappers.getMapper(SourceTargetMapper.class);

   
@Mapping(target = "localDateTime", expression = "java(emptyToNull(src.getDateString()))", dateFormat = "yyyy-MM-dd:HH:mm")
   
Target toTarget(Source src);

   
default String emptyToNull(String s) {

       
return s == null || s.isEmpty() ? null : s;
   
}
}

Unfortunately the generated Code does not do the conversion:
  
public class SourceTargetMapperImpl implements SourceTargetMapper {
 
@Override

   
public Target toTarget(Source src) {

       
if ( src == null ) {

           
return null;
       
}

       
Target target = new Target();

// no conversion here!
        target
.setLocalDateTime( emptyToNull(src.getDateString()) );

       
return target;
   
}
}

But i picked up the idea and did it this way:

@Mapper
public interface SourceTargetMapper {

   
SourceTargetMapper INSTANCE = Mappers.getMapper(SourceTargetMapper.class);

   
@Mapping(target = "localDateTime", expression = "java(emptyToNull(src.getDateString()))")
   
Target toTarget(Source src);

   
default LocalDateTime emptyToNull(String s) {
       
if (s == null || s.isEmpty()) return null;
       
return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd:HH:mm"));
   
}
}

It works but i am not sure if this is what you meant.

Gunnar Morling

unread,
Mar 2, 2017, 3:00:17 PM3/2/17
to karl....@googlemail.com, mapstruct-users
Ah yes, of course. I believed the expression value would be subject to
conversion, but it actually isn't.

Your last snippet looks good, you can omit the expression() altogether
though. If there is a custom method for mapping String to LocalDate
Time it will take precedence over the built-in conversion routine and
automatically invoked in the generated code.

--Gunnar


2017-03-02 13:01 GMT+01:00 karl.w.roth via mapstruct-users
<mapstru...@googlegroups.com>:

karl....@googlemail.com

unread,
Mar 3, 2017, 4:39:32 AM3/3/17
to mapstruct-users
Thanks Gunnar,

just to finish this issue.
This is what you are talking about:
@Mapping(target = "localDateTime", source = "dateString")
   
abstract Target toTarget(Source src);


   
LocalDateTime emptyToNull(String s) {
       
if (s == null || s.isEmpty()) return null;
       
return LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd:HH:mm"));
   
}
 Its pretty much the same but alot more straight forward. And it works ;)



Am Donnerstag, 2. März 2017 11:25:47 UTC+1 schrieb karl....@googlemail.com:
Reply all
Reply to author
Forward
0 new messages