Offer a flag for exact numeric conversions
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 35/100
Direzione di ricerca
Inizia esaminando il comportamento esistente di typeConversionPolicy e le conversioni numeriche generate descritte nell’issue, incluse BigDecimal-to-Integer e altre conversioni potenzialmente con perdita. Definisci come un flag precisionLossStrategy dovrebbe essere applicato a tutte queste conversioni, mantenendo IGNORE come valore predefinito. Il lavoro è completato quando la modalità strict produce conversioni senza perdita o il comportamento di errore specificato, senza richiedere metodi personalizzati per campo.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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
qualifiedByNamewith 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=ERRORand 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
- Lingua principale
- Java
- Stelle
- 7.7k
- Fork
- 1.1k
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di mapstruct/mapstruct
-
bug test
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
-
bug
Difficoltà 3/5 1-2 giorni Idoneità per principianti 68/100
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 68/100
-
bug JSpecify
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 72/100
Tutte le issue di mapstruct/mapstruct
Issue simili
-
executions.Query — startDate and timeRange filters are sent with inverted comparison operators Apertaarea/plugin
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
kestra-io/plugin-kestra#190 ·
-
litertlm-android AAR ships no consumer ProGuard rules → "mid == null" SIGABRT in minified apps Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
google-ai-edge/LiteRT-LM#3739 ·
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
integra-team-red/meet-map#249 ·
-
[Studio][Bug] Cancelled create-user dialog keeps the password and admin switch for the next attempt Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
apache/rocketmq-dashboard#5064 ·