Как сделать сущность доступной только для чтения?



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



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

569   9  

9 ответов:

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

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

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

  • PRO: стандарт JPA - не hibernate specific
  • PRO: очень безопасно
  • CON: показывает только попытки записи runtime. Если вы хотите время компиляции проверьте, вы не должны реализовывать сеттеры.

в вашей сущности добавить 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("...");
    }
}

Если ваша реализация JPA является hibernate - вы можете использовать аннотацию Hibernate Entity

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

очевидно, что это свяжет вашу модель в спящий режим, хотя.

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

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

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

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

реализация Eclipselink также предлагает вам @ReadOnly аннотация на уровне сущности

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

либо автоматизировать решение Mac (сделать AspectJ ввести @Column аннотация):

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

или объявить ошибку компилятора для всех методов доступа к set:

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

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

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

Comments

    Ничего не найдено.