Вопрос о EJB и JPA - PullRequest
       10

Вопрос о EJB и JPA

2 голосов
/ 14 июля 2011

Я использую EJB 3.1 и JPA 2.0.

Я приведу вам пример, чтобы объяснить мои сомнения и попросить подсказки о том, что является хорошей практикой, а что нет.

Допустим, у меня есть EJB, это пользовательский Фасад. Итак, у вас есть что-то вроде этого:

@Stateless
public class UserRepository {

  public User find(Long id) {
    ...do user lookup using entitymanager.
  }

}

Хорошо, теперь давайте скажем, что я возвращаю сущность User из этого и что у этой сущности есть коллекция комментариев (комментарий также является сущностью).

У меня может быть хранилище комментариев с методом findCommentsByUser(Long userId), или я могу получить пользователя и вызвать метод getComments(). Может быть, этот случай прост, но я сталкивался с этим решением много раз, иногда не зная, что лучше.

Кроме того, допустим, я хочу добавить комментарий, должен ли я добавить его в коллекцию комментариев, в которой находится сущность, и в которой объединена сущность, или у меня должен быть метод addComment(Long userId, Comment newComment)?

Я ищу советы или лучшие практики по этому поводу. Если вам нужны дополнительные разъяснения, пожалуйста, не стесняйтесь спрашивать.

EDIT:

Я нашел комментарии до сих пор полезными, однако заметьте это, это не совсем о пользователях и комментариях, я просто придумал это, чтобы объяснить мою ситуацию. Речь идет о том, удобно ли смешивать оба подхода (что я думаю, что нет), или один лучше другого. Мне понравилось предложение "всегда сохраняться через репозитории". Но тот факт, что у меня есть метод репозитория fetchComments() и getComments() в пользовательской сущности, создает точки входа для той же функциональности, так как мне с этим справиться? Кроме того, производительность (1 запрос против 2 запросов) не очень важна, потому что я буду также извлекать пользовательскую сущность, так что на самом деле я ничего не сохраняю.

Ответы [ 5 ]

3 голосов
/ 14 июля 2011

Мы обычно работаем только с отсоединенными объектами в наших приложениях, поэтому у нас есть менеджер доступа к данным для извлечения и обновления объектов. Тогда мы знаем, что все, что мы делаем в нашей бизнес-логике, не будет сохранено без специального обращения. Я также хотел бы получить комментарии с пользовательской сущностью, но удостовериться, что она не сохраняется до тех пор, пока не будет явно вызвана.

2 голосов
/ 14 июля 2011

У меня может быть хранилище комментариев с методом findCommentsByUser (Long userId), или я могу получить пользователя и вызвать getComments ()

Я бы сказал, что из производительность с точки зрения, первый вариант немного лучше, потому что вы не читаете пользователя (1 запрос), а затем комментарии (другой запрос).Первый делает это одним выстрелом.

С другой стороны, я нахожу второй более читабельный , абстрактный и объектно-ориентированный подход.Я бы использовал это.

1 голос
/ 15 июля 2011

Есть несколько соображений, на которые нужно обратить внимание, надеюсь, я приведу их здесь для вас.

  1. Модель предметной области является важным фактором в EJB3.В вашем примере, если вы видите, что модель вашего домена позволяет вам извлекать комментарии лениво, потому что в любом потоке вы сначала показываете данные пользователя, а затем его комментарии.
  2. В некоторых случаях ваша коллекция (я имею в виду комментарии здесь) может содержатьмного данных, в этом случае вряд ли вопрос строковых данных, поэтому это не главная проблема, но если бы это были реальные данные приложения, всегда выбирайте переходные отношения и предоставляйте соответствующие методы для их независимого извлечения.
  3. ЕгоНикогда не рекомендуется выставлять вашу коллекцию внутри сущностного компонента для внешнего мира, поэтому, если у вас отношения OneToMany или ManyToMany, вы должны предоставить три базовых метода для коллекций (добавить, удалить, получить).
  4. Метод Collections.unmodifiableCollection должен бытьиспользуется при возврате коллекций из метода get.
  5. Всегда используйте Set, если вы используете коллекции внутри сущностей, помните, что они не допускают дублирование.
  6. В вашем случае коллекция комментариев имеет прямую зависимость on user, так что вы должны использовать каскадный тип в user для сохранения комментариев.
  7. Я не уверен, зачем вам нужен UserRepository, потому что метод em.find сделает вашу работу за вас.
  8. По умолчанию для отношения OneToManyfetchtype ленив, поэтому, если вы хотите загружать его, вам нужно его указать.

Надеюсь, что эти рекомендации помогут решить вашу проблему.

С уважением, Amit

1 голос
/ 14 июля 2011

Я думаю, что это в значительной степени зависит от требований, от того, какой детальный контроль над процессом вы хотите иметь (это часто зависит от требований к производительности и ожидаемой нагрузки и т. Д.). Если комментарии никогда не будут получены независимо, я бы оставил их только в качестве ссылки внутри User.

Если, однако, вы хотите получать комментарии независимо от пользователя, или вы хотите выполнить некоторые другие связанные с комментариями запросы (например, все комментарии для пользователей в группе A), то я бы создал отдельный CommentsRepository.

Если вы хотите иметь возможность добавлять комментарий пользователю, который не загружен из БД, но у вас есть внешний ключ, вы можете просто добавить комментарий через CommentsRepository, как вы предлагали (также добавив комментарий параллельный список комментариев пользователя, и сохранение этих двух списков в БД может привести к «странному поведению»).

1 голос
/ 14 июля 2011

Как правило, вы добавляете метод getComments () в ваш пользовательский объект. Если вы хотите добавить один, вы должны добавить его в пользовательский набор и затем вызвать update для объекта пользователя.

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