Hacktoberfest 2026: as issues que os mantenedores marcaram para outubro, abertas e boas para iniciantes. Ver issues do Hacktoberfest

Offer a flag for exact numeric conversions

Aberta
#4,017 2 comentários 0 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
5/5
Tempo estimado
Mais de uma semana
Facilidade para iniciantes
35/100
Tipo de issue
Funcionalidade
Clareza
Razoavelmente clara
Status de atividade
Pouca atividade
Stack de tecnologia
java
Domínio
tooling

Direção de pesquisa

Comece examinando o comportamento existente de typeConversionPolicy e as conversões numéricas geradas descritas na issue, incluindo BigDecimal-to-Integer e outras conversões potencialmente com perda. Defina como um sinalizador precisionLossStrategy seria aplicado a todas essas conversões, preservando IGNORE como padrão. O trabalho estará concluído quando o modo estrito produzir conversões sem perda ou o comportamento de falha especificado, sem exigir métodos personalizados por campo.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

Use case

As of now, numeric conversions like BigDecimal to Integer use BigDecimal.intValue(), which is a narrowing conversions, discard fractional part and may overflow. My applications, and probably from many others, would benefit from a more strict behavior, like that provided by BigDecimal.intValueExact().

That should be applicable for all potentially lossy conversions (double-to-int, long-to-int, etc), potentially even for cases like converting a timestamp with nanosecond precision into a datatype format that only goes up to millisecond.

I think an ideal solution would be a new flag for configuring behavior, like mapstruct.precisionLossStrategy with values like IGNORE and ERROR, with IGNORE as default to ensure backwards compatibility for existing code.

Example code with current behavior:

@Mapper
public interface MyMapper {

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

    IntegerRecord map(BigDecimalRecord value);
    BigDecimalRecord map(IntegerRecord value);

    record BigDecimalRecord(BigDecimal number) {}
    record IntegerRecord(Integer number) {}

    static void main(String[] args) {
        System.out.println(INSTANCE.map(new BigDecimalRecord(new BigDecimal("1.9"))));
    }
}

Output:

IntegerRecord[value=1]

Desired output:

java.lang.ArithmeticException: Rounding necessary
Generated Code

Currently generated code:

    @Override
    public MyMapper.IntegerRecord map(MyMapper.BigDecimalRecord bigDecimalRecord) {
        // ...
        if ( bigDecimalRecord.number() != null ) {
            number = bigDecimalRecord.number().intValue();
        }
        // ...
    }

Desired generated code:

    @Override
    public MyMapper.IntegerRecord map(MyMapper.BigDecimalRecord bigDecimalRecord) {
        // ...
        if ( bigDecimalRecord.number() != null ) {
            number = bigDecimalRecord.number().intValueExact();
        }
        // ...
    }
Possible workarounds

The current alternatives I see now:

  • using qualifiedByName with a custom method to ensure lossless conversion
    • but that easily gets overwhelming if dealing with lots of numeric field mappings
    • moreover, one need to manually apply it to every field pair, and that makes missing some a very likely scenario
  • using typeConversionPolicy=ERROR and providing manual conversion methods for all required conversions
    • less error prone, but still requires setting the flag everywhere or importing a shared config everywhere (mistake opportunities), plus all the boilerplate code that could be provided by MapStruct

If there is a better way to achieve the described behavior, I'd be glad to know.

MapStruct Version

1.6.3

Linguagem predominante
Java
Estrelas
7.7k
Forks
1.1k
Métricas de merge de PRs
Nenhum PR com merge em 30d

Guia de contribuição

Abrir o guia de contribuição

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de mapstruct/mapstruct

Todas as issues de mapstruct/mapstruct

Issues semelhantes

Mais issues de Java

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.