Автор оригинала: Vlad Mihalcea.
StackOverflow-это нескончаемый источник больших вопросов. На этот раз мы рассмотрим этот вопрос об использовании Java 1.8 Необязательно
с JPA и гибернацией .
Java 1.8 представила java.util. Необязательный
объект-контейнер, который может содержать или не содержать определенное значение. Объединение Необязательно
и потоков очень удобно. Поэтому вы можете захотеть, чтобы некоторые атрибуты сущности, допускающие обнуление, были представлены как Необязательные
.
В этой статье мы продемонстрируем, каковы предостережения при использовании Необязательно
с атрибутами сущностей и как вы можете их преодолеть.
Давайте предположим, что у нас есть следующая модель сущности:
Сущность Post
является корнем в нашей совокупности сущностей. Может быть несколько Комментариев к сообщению(комментариям)
связано с
Сообщением , и каждый
Комментарий к сообщению может иметь
Приложение . Поскольку
Вложение не является обязательным, имеет смысл использовать для него
Необязательный
Файл java.util. Необязательно
не реализует Сериализуемый
интерфейс. По этой причине мы никогда не должны отображать атрибут сущности как Необязательный
, потому что это ограничит использование сущности.
Например, у нас может быть отдельный экземпляр, хранящийся в HttpSession
, потому что мы выполняем рабочий процесс длительного разговора . Каждый объект, хранящийся в HttpSession
, должен быть Сериализуемый
потому что сеанс может быть сгруппирован на нескольких веб-узлах.
Если вы используете Java EE и компоненты сеанса с сохранением состояния, то вы должны убедиться, что все сущности сериализуемы, так как в противном случае процесс пассивации завершится неудачей .
По всем этим причинам атрибут сущности не должен отображаться как java.util. Необязательно
.
Но только потому , что мы не можем отобразить атрибут сущности как Необязательный
, это не означает, что мы не можем предоставить его с помощью Необязательного
контейнера. Если мы используем сохраняемость доступа на основе полей, то базовый атрибут сущности может быть сопоставлен с использованием фактического сохраняемого типа, в то время как метод получения может использовать Необязательно
вместо этого.
@Entity(name = "PostComment") @Table(name = "post_comment") public class PostComment implements Serializable { @Id @GeneratedValue private Long id; private String review; @ManyToOne(fetch = FetchType.LAZY) private Post post; @ManyToOne(fetch = FetchType.LAZY) private Attachment attachment; public OptionalgetAttachment() { return Optional.ofNullable(attachment); } public void setAttachment(Attachment attachment) { this.attachment = attachment; } //Other getters and setters omitted for brevity }
Вот и все!
Если вы используете доступ на основе свойств, то получатель должен предоставить фактический сохраняемый тип, и в этом случае вам потребуется отдельный метод @Transient
, который использует Необязательно
тип возвращаемого метода.
Предполагая, что у нас есть следующие сущности:
byte[] coverContent = new byte[] {1, 2, 3}; Post post = new Post(); post.setId(1L); post.setTitle("High-Performance Java Persistence"); entityManager.persist(post); PostComment comment1 = new PostComment(); comment1.setPost(post); entityManager.persist(comment1); Attachment cover = new Attachment(); cover.setContent(coverContent); entityManager.persist(cover); PostComment comment2 = new PostComment(); comment2.setPost(post); comment2.setAttachment(cover); entityManager.persist(comment2);
Если у нас уже есть список Комментариев к публикациям
:
Listcomments = entityManager.createQuery( "select pc " + "from PostComment pc " + "join pc.post p " + "where p.id = :postId", PostComment.class) .setParameter("postId", 1L) .getResultList();
Мы можем обработать Вложения(ы)
следующим образом:
Attachment notAvailable = getNotAvaillableImage(); Listattachments = comments .stream() .map(pc -> pc.getAttachment() .orElse(notAvailable)) .collect(Collectors.toList());
Если его нет Вложение
уже установлено, мы можем использовать значение по умолчанию N/A изображение.
При использовании JPA и гибернации вы можете использовать Java 1.8 Необязательно
в сущностях вашей модели домена. Однако вы должны убедиться, что не используете его в качестве постоянного типа свойства.