Распознает ли Hibernate изменения по результату получения? - PullRequest
0 голосов
/ 11 января 2012

Как Hibernate распознает изменение объекта?Это проверка поля напрямую или использование соответствующего метода Геттера?

Скажем, у меня есть столбец цен в базе данных.При определенных условиях цена конвертируется.Могу ли я сделать это в методе Getter и вернуть преобразованное значение без изменения значения этого столбца, если я сохраню этот объект?Изменение, внесенное установщиком этого свойства, должно изменить столбец.

Каково поведение по умолчанию?Можно ли это изменить?Это хорошая практика или ее следует избегать с помощью метода "getConvertedPrice", потому что поведение может измениться с другой конфигурацией / версией, которая приводит к труднодоступным ошибкам?

Редактировать: Пример запросакод ...

@Entity
@Table(name="items")
public class Item {
    /*...*/
    @Column(name="item_price")
    private double price;

    @Column(name="item_currency")
    // More enum mapping ...
    private Currency currency;

    public void setPrice(double price) {
        this.price = price;
    }

    public double getPrice() {
        if(getCurrency()!=Currency.US_DOLLAR) {
            return price * CurrencyService.getCurrentRate(getCurrency());
        } else {
            return price;
        }
    }
    /*..*/
}

Ответы [ 4 ]

2 голосов
/ 11 января 2012

Это зависит от типа доступа объекта.По умолчанию это определяется из размещения аннотаций сопоставления (в полях или в свойствах).

Вы можете переопределить тип доступа для определенного поля, используя аннотацию @Access (или @AccessType для старых версий Hibernate).

1 голос
/ 11 января 2012

Хорошо, что недостаток (который все же стоит) в использовании Hibernate. Он берет под контроль ваши сущности. Я приведу два примера:

  1. У вас должен быть конструктор по умолчанию, который хотя бы защищен. Это ставит под угрозу безопасность потоков и не позволяет сделать вашу сущность неизменной (что имеет много преимуществ) .
  2. Если ваша сущность ссылается на дочерние сущности как на ассоциацию OneToMany, у вас, естественно, есть какой-то public Collection<Child> getChildren() метод. Но если вы хотите предоставить неизменяемую коллекцию ваших детей - Hibernate потерпит неудачу.

Так. Постарайтесь отделить любую логику от вашего сопоставленного объекта (сущности) настолько, насколько это возможно. Рассматривайте свою сущность как структуру, целью которой является связь с БД. Поместите свою логику в слой услуг.

EDIT После прочтения комментария Воо: на самом деле неизменность - это не то, что вам обычно требуется для сопоставляемых объектов. Тем не менее, безопасность потоков очень важна.

0 голосов
/ 11 января 2012

Вы можете использовать @Transient Аннотация , любое переходное свойство со знаком не будет сохранено.
При заполнении объекта из базы данных переходное свойство будет установлено с использованием исходного значения.

Во всем приложении используйте эту временную переменную, и перед сохранением (вы можете использовать аннотацию @PrePersist) вы можете заполнить значение из временной переменной.

0 голосов
/ 11 января 2012

Hibernate на самом деле не заботится об объекте / классе. Он знает только о конфигурации сопоставления, которую вы задали для объекта. Hibernate будет искать метод GET для свойства, указанного вами в вашем отображении hibernate xml. Таким образом, вы можете изменить свой метод get так, чтобы он делал так, как вы хотите, и это изменение не будет сохранено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...