BigDecimal para computar valores monetários

olá, estou com uma dúvida se estou usando corretamente a classe BigDecimal.

Eu tenho um campo decimal(10,2) no banco postgresql, que é capaz de armazenar um número positivo até no máximo 10^8 (10 é o número total de dígitos decimais do número, e 2 a parte fracionária). Quando eu capturo esse dado na minha aplicação eu armazeno em um BigDecimal. Daí eu vou realizando as operações aritméticas sem restrição de precisão ou escala. Quando eu vou armazenar no banco, eu verifico se o valor do BigDecimal é maior que o máximo do tipo no banco, se for eu coloco o valor máximo. Também arredondo para a escala ser igual a parte fracionária do tipo no banco. Trabalhando desse jeito, sem restrições no BigDecimal, eu acredito que consigo a exatidão necessária quando se trabalha com valores monetários, pois eu só vou perder precisão/arredondar quando for armazenar no banco.

Minha dúvida é se eu estou trabalhando de forma correta, ou deveria restringir o valor do BigDecimal para nunca ser maior que o máximo do banco, após cada uma das operações aritméticas que forem realizadas.

Também tenho dúvida se esta forma é realmente a ideal para se trabalhar com valores monetários.
:-o

Você está trabalhando corretamente, a classe BigDecimal é a mais indicada para manipular valores monetários. Quanto à restrição de valor máximo, é suficiente você checar se o valor é válido apenas no momento de gravar a informação no Banco de Dados. Nunca trabalhei com o PostgreSQL, mas, se for parecido com outros BD’s com que tenho experiência, haverá um erro de execução se você tentar gravar um valor inteiro muito alto, porém dígitos extras na parte fracionária serão simplesmente arredondados e não causarão erros de execução.

Você não deveria trabalhar com regras de cálculo baseadas somente no que o banco faz ou deixa de fazer.

Deveria sim é perguntar para o seu cliente quais são essas regras, qual o tipo de arredondamento de fração vão praticar, e qual o limite de valores com que vão trabalhar. Se não tiver um cliente, então defina você mesmo e documente isto. Provavelmente já há regras, leis nacionais ou internacionais que tratam disso, principalmente que os bancos utilizam (pelo menos do arredondamento, não dos limites)

O objetivo é já chegar no banco com o valor certo, ele só vai armazenar as coisas, sem fazer arredondamentos nem dar erros.

no meu caso eu não tenho cliente, é trabalho de estudo. Eu defini o limite para ser 10 dígitos decimais, sendo 2 deles reservados para a parte fracionária. Então o limite é 99999999.99

nesse caso de já ir para o banco com o valor certo, eu tenho que observar na minha aplicação se esse limite foi extrapolado após cada operação? imagine o seguinte caso

   BigDecimal valor = new BigDecimal("99999999.99");
   BigDecimal quantidade = new BigDecimal("2");
   BigDecimal desconto = new BigDecimal("5.82");
   BigDecimal total = valor.subtract(valor.multiply(desconto).divide(new BigDecimal("100"))).multiply(quantidade);

neste caso o limite de 99999999.99 foi extrapolado, então antes de eu efetuar outras operações no total, eu devo restringir ele para o máximo?

Vou dar um pequeno exemplo do que acontece na própria API do Java quando ultrapassamos os valores máximos de seus tipos:

[code]
Integer i = new Integer(Integer.MAX_VALUE);
System.out.println(i);

    Integer j = new Integer("2147483648");
    System.out.println(j);

[/code]O resultado é 2147483647 Exception in thread "main" java.lang.NumberFormatException: For input string: "2147483648" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) at java.lang.Integer.parseInt(Integer.java:465) at java.lang.Integer.<init>(Integer.java:660) at testes.Main.main(Main.java:10)

Ela lança uma exceção. Normalmente eu faria o mesmo, e a trataria falando para o usuário sobre problema.