mapstruct / mapstruct/mapstruct

DeepClone does not clone java.util.Date fields but perform a copy reference

Open
#3,931 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Java
Stars
7.7k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

### Expected behavior

I have a mapper annotated DeepClone to perform a copy clone of some bean. I notice that the generated implementation on java.util.Date field it perform a simple `a.setDate(b.getDate())`. This could be ok for String or BigDecimal object that are immutable but old java Date object are not immutable that mean if I change `b.getDate().setTime(1l)` it will also update date in the bean a.

What I expect is that in case of DeepClone it produce the following code:
```
@Override
public BeanA clone(BeanA value) {
if ( value == null ) {
return null;
}

BeanA beanA = new BeanA();
if (source.getDate() != null) {
beanA.setDate(new Date(source.getDate().getTime())); // expected behaviour
}

return beanA;
}
```

### Actual behavior

The generated code is
```
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2025-09-16T10:12:55+0200",
comments = "version: 1.6.3, compiler: Eclipse JDT (IDE) 3.41.0.v20250213-1140, environment: Java 21.0.6 (Eclipse Adoptium)"
)
public class ICloneMapperImpl implements ICloneMapper {

@Override
public BeanA clone(BeanA value) {
if ( value == null ) {
return null;
}

BeanA beanA = new BeanA();
beanA.setDate(source.getDate());

return beanA;
}
}
```

### Steps to reproduce the problem

Create the following classes
```
public class BeanA {
private Date date;
public Date getDate() { return date; }
public void setDate(Date value) { date = value; }
}

@Mapper(mappingControl = DeepClone.class)
public interface ICloneMapper {
BeanA clone(BeanA source);
}
```

### MapStruct Version

MapStruct 1.6.3

### Workaround

In the ICloneMapper I have to define a method like this:
```
default Date map(Date value) {
return value != null ? new Date(value.getTime()) : null;
}
```
to get the clone of date.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the DeepClone mapping control and the ICloneMapper reproduction shown in the issue. Check how the generated mapper handles java.util.Date fields; done means the generated clone does not share the mutable Date reference, including when the original date is later changed.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.