Как сделать Entity только для чтения? - PullRequest
62 голосов
/ 25 февраля 2011

Как правильно сделать Entity доступным только для чтения с JPA? Я хочу, чтобы моя таблица базы данных никогда не изменялась вообще программно.

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

Ответы [ 9 ]

44 голосов
/ 25 февраля 2011

Решение состоит в том, чтобы использовать аннотацию на основе полей, чтобы объявить ваши поля как protected и предложить только публичный получатель.При этом ваши объекты не могут быть изменены.

(Это решение не зависит от сущности, это просто способ создания неизменяемых объектов)

29 голосов
/ 25 августа 2015

Вы можете создать пуленепробиваемую сеть безопасности для вашей сущности с помощью прослушивателей жизненного цикла JPA.

  • PRO: стандарт JPA - не специфичный для спящего режима
  • PRO: очень безопасный
  • CON: показывает только попытки записи в время выполнения .Если вам нужна проверка времени компиляции , вам не следует реализовывать сеттеры.

В вашей сущности добавьте EntityListener, например:

@Entity
@EntityListeners(PreventAnyUpdate.class)
public class YourEntity {
    // ...
}

Реализацияваш EntityListener, чтобы выдать исключение, если произойдет какое-либо обновление:

public class PreventAnyUpdate {

    @PrePersist
    void onPrePersist(Object o) {
        throw new RuntimeException("...");
    }

    @PreUpdate
    void onPreUpdate(Object o) {
        throw new RuntimeException("...");
    }

    @PreRemove
    void onPreRemove(Object o) {
        throw new RuntimeException("...");
    }
}
21 голосов
/ 12 октября 2011

Если ваша реализация JPA находится в спящем режиме - вы можете использовать аннотацию спящего объекта Entity

@org.hibernate.annotations.Entity(mutable = false)

Очевидно, что это свяжет вашу модель с гибернацией.

18 голосов
/ 09 мая 2012

Hibernate также имеет аннотацию org.hibernate.annotations.Immutable, которую вы можете поместить в тип, метод или поле.

13 голосов
/ 25 февраля 2011

Я думаю, что вы ищете, чтобы ваша сущность была неизменной. Hibernate поддерживает это; JPA (по крайней мере, JPA 1.0) нет. Я полагаю, что вы можете контролировать это, предоставляя только получатели и следя, чтобы получатели возвращали только неизменяемые значения.

11 голосов
/ 25 февраля 2011

IIRC вы можете установить каждое поле на insertable = false и updatable = false в ваших @Column аннотациях, но я уверен, что должен быть лучший метод ...:)

Я не думаю, это помогает?

10 голосов
/ 25 февраля 2011

Реализация Eclipselink также предлагает вам аннотацию @ReadOnly на уровне объекта

6 голосов
/ 25 февраля 2011

Это, вероятно, заразит меня отрицательным голосом, потому что я всегда голосую за то, что предложили его, но вы можете использовать AspectJ несколькими способами для обеспечения этого:

Либо автоматизируйте решение Mac (make AspectJ внедряет аннотацию @Column):

declare @field : (@Entity *) *.* : @Column(insertable=false);

Или объявляет ошибку компилятора для всех прав доступа к заданным методам:

declare error : execution((@Entity *) *.set*(*) );

Недостаток: вам необходимо добавить компиляцию AspectJ в вашпостроить, но это легко, если вы используете муравей или maven

3 голосов
/ 20 марта 2018

Если вы используете spring-data или иным образом используете шаблон Repository, не включайте никакие методы save / update / create / insert / etc в Repository для этой конкретной сущности. Это можно обобщить, имея базовый класс / интерфейс для объектов, доступных только для чтения, и обновляемый объект, который расширяет класс, доступный только для чтения, для обновляемых объектов. Как отмечали другие авторы, сеттеры также можно сделать закрытыми, чтобы разработчики не могли случайно установить значения, которые они затем не смогут сохранить.

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