2014-10-07 3 views
1

Как определить подходящую область CDI для репозитория JPA, как показано ниже?Какая область CDI должна быть предпочтительной для репозитория JPA

@Transactional 
public class CategoryRep extends EntityRepository<Integer, Category> { 

    private static final long serialVersionUID = 856370976984333182L; 

    public List<Category> getAllCategories() { 
     // TODO 
    } 

    public List<Post> getAllPostsOfCategory(Integer categoryId) { 
     // TODO 
    } 

    @Transactional(value = TxType.REQUIRES_NEW, rollbackOn = RuntimeException.class) 
    public void createCategory(final String name, final String description) 
      throws DaoJpaException { 
     // TODO 
    } 
} 

я могу думать только два прицелов CDI:

  1. @SessionScope: Для меня это, как представляется, наиболее соответствующий объем, так как один экземпляр предназначен для активного сеанса.
  2. @Dependent: Разумный, поскольку такой экземпляр будет вписываться в жизненный цикл объекта, в который он будет введен.

Всех остальных CDI-прицелы не подходит по-моему:

  1. @ApplicationScoped: Поскольку приложение области действия хранилище будет создано только один раз времени, вызов, как: entityManager.clear() будет вызывать что все экземпляры всех текущих сеансов также будут отключены. Кроме того, этот единственный репозиторий должен обрабатывать все входящие запросы. Возможно, эта область подходит для репозитория только для чтения?
  2. @RequestScope: Я думаю, что нет необходимости в новом экземпляре репозитория для каждого входящего запроса.
  3. @ConversionScoped: Конверсии обычно выполняются на уровне графического интерфейса пользователя. Если я хочу, чтобы репозиторий погиб после окончания преобразования, я могу определить его как @Dependent.

Итак, есть ли какие-либо рекомендации, известные этой проблеме?

ответ

3

Чтобы описать все варианты

  • Session Scope на самом деле не имеет смысла, потому что ваше хранилище должно быть лицо без гражданства, таким образом, сеанс не должен иметь никакого значения для него (хотя бы решить проблему параллелизма
  • Dependent scope может быть хорошим вариантом, однако это может привести к утечке памяти (вы никогда не можете быть уверены, что зависимый объект будет удален из памяти)
  • Область разговора тоже не имеет смысла, это тот же случай, что и сеанс сфера охвата

Так что я бы ни с

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

Так что, если бы я был вами, я бы выбрал репозиторий области запроса, это самый простой вариант, и вы избегаете всех проблем таким образом.

+0

Благодарим, что атрибут '@ Version' решает проблему параллелизма, используя' @ ApplicationScoped'? –

+0

Честно говоря, я не уверен, потому что javadoc говорит только о сохранении целостности при слиянии сущности, которая мне кажется, что этого недостаточно. –

+0

Я думаю, что использование оптимистической и пессимистической блокировки должно решить проблему параллелизма. –

1

Вы должны использовать @ApplicationScoped.

EntityManager должен использоваться для каждого запроса и не использоваться повторно.

При попрошайничестве запроса вы создаете entityManager, когда он завершает фиксацию или откат.

@Dependent будет иметь одинаковую область своего «хоста», если вы введете его в @RequestScoped, а bean будет иметь тот же объем.

@SessionScoped следует использовать только для небольших данных (например, для входа в систему и разрешения).

Смежные вопросы