2015-04-14 5 views
3

Я использую hibernate для сохранения моих данных. Это финансовое приложение, и мне трудно найти самую основную сущность приложения, которая является «Деньгами». Я использовал JodaMoney, но он неизменен, поэтому я не могу найти хороший способ его сохранить. И не сохраняя мои деньги в базе данных, нет смысла делать заявку. Что я буду делать с неизменностью, когда я не могу даже сохранить состояние своего объекта? Затем я начал создавать свои собственные «Деньги» (поля как BigDecimal amount и java.util.Currency для валюты), я хотел использовать «Currency» для java.util. Но у этого нет публичного конструктора, поэтому спящий режим не может этого сохранить. Прошу вас посоветовать, как с этим бороться?Как сохранить классы, такие как java.util.Currency?

EDIT1: Код для большинства базового класса:

@Entity 
public class BasicMoney { 

    @Embedded 
    @Id 
    private BigDecimal amount; 
    @Embedded 
    private Currency currency; 
    //getters and setters, other methods 
} 

Теперь, когда я создать объект этого класса и попытаться сохранить его в базу данных, она не работает. Hibernate throws org.hibernate.InstantiationException: конструктор по умолчанию для объекта:: java.util.Currency. Итак, это проблема, с которой я столкнулся.

+0

много теории, никакого кода .... это не лучший способ задать вопрос !!! –

+0

Опубликовать то, что вы пробовали – Shamse

+0

@AnkitLamba Я добавил код, это очень простой код, но мой главный вопрос - как справиться с такими ситуациями? –

ответ

4

Вы можете использовать обходной путь

@Embedded 
String currency; 

public void setCurrency(Currency currency) { 
    this.currency = currency.getCurrencyCode(); 
} 

public Currency getCurrency() { 
    return Currency.getInstance(currency); 
} 
+0

Большое спасибо !!! это имеет смысл. У меня есть только одна проблема с этим, каждый раз, когда я вызываю метод getCurrency(), ему нужно будет создать новый объект валюты, так что бы это было дорого? Работа, вокруг которой я могу думать, делает еще одно поле @Transient, которое постоянно сохраняет объект Currency, поэтому получателю не нужно создавать его каждый раз, когда он вызывается. что ты думаешь об этом? –

+1

попробуйте System.out.println (Currency.getInstance («USD») == Валюта.деЫпзЬапсе ("USD")); он возвращает true –

+1

okay yes его возвращение true, так что означает, что Currency class возвращает тот же экземпляр. Я просто проверил метод в java.util.Currency также, и я получаю его, он поддерживает карту валютных объектов с помощью String Key. Таким образом, он не создает новые объекты каждый раз. Еще раз спасибо Евгению! :) –

1

Вместо того, чтобы иметь дело с валютной строки и суммы, научить Hibernate о вашем типе вместо этого. Таким образом, вы бы:

private Money amount; 

вместо

private BigDecimal amount; 
private String currency; 

так что вам не нужно конвертировать повсюду.

Вот как я это делаю:

1) Вместо JodaMoney используйте JavaMoney, проект JSR-354, который, как ожидается, будут включены в Java 9. Если вы хотите придерживаться JodaMoney, вы не необходимо выполнить шаг № 3 ниже.

2) Добавить это UserType library в своем пути к классам

3) Создать этот простой класс:

public class CustomPersistentMoneyAmountAndCurrency extends AbstractMultiColumnUserType<MonetaryAmount> { 

    private static final ColumnMapper<?, ?>[] COLUMN_MAPPERS = new ColumnMapper<?, ?>[] { new CustomStringColumnCurrencyUnitMapper(), new BigDecimalBigDecimalColumnMapper() }; 

    private static final String[] PROPERTY_NAMES = new String[]{ "currency", "number" }; 

    @Override 
    protected ColumnMapper<?, ?>[] getColumnMappers() { 
     return COLUMN_MAPPERS; 
    } 

    @Override 
    protected Money fromConvertedColumns(Object[] convertedColumns) { 

     CurrencyUnit currencyUnitPart = (CurrencyUnit) convertedColumns[0]; 
     BigDecimal amountPart = (BigDecimal) convertedColumns[1]; 
     return Money.of(amountPart, currencyUnitPart); 
    } 

    @Override 
    protected Object[] toConvertedColumns(MonetaryAmount value) { 

     return new Object[] { value.getCurrency(), value.getNumber().numberValue(BigDecimal.class) }; 
    } 

    @Override 
    public String[] getPropertyNames() { 
     return PROPERTY_NAMES; 
    } 
} 

4) Теперь, куда вы хотите, чтобы использовать это в ваших лицах вы могли бы сделать:

@TypeDefs(value = { 
     @TypeDef(name = "moneyAmountWithCurrencyType", typeClass =  CustomPersistentMoneyAmountAndCurrency.class) 
}) 
@Entity 
@Table(name = "account_entry") 
public class AccountEntry { 

    private Money referenceMoney; 
    ... 
    @Basic(optional = false) 
    @Columns(columns = { 
      @Column(name = "reference_money_currency", nullable = false, length = 3 ), 
      @Column(name = "reference_money", nullable = false ) 
    }) 
    @Type(type = "moneyAmountWithCurrencyType") 
    public Money getReferenceMoney() { 
     return this.referenceMoney; 
    } 
    } 

И все. Вы получите сильную типизацию на всем протяжении.

Смежные вопросы