Costumo usar o Hibernate em combinação com o framework Spring e seus recursos de demarcação de transação declarativa (por exemplo, @Transactional ).
Como todos sabemos, o Hibernate tenta ser o mais não invasivo e transparente possível, mas isso se mostra um pouco mais desafiador quando se trata de lazy-loaded
relacionamentos.
Vejo uma série de alternativas de design com diferentes níveis de transparência.
- Faça relacionamentos não carregados lentamente (por exemplo,
fetchType=FetchType.EAGER)
- Isso viola toda a ideia de carregamento lento.
- Inicializar coleções usando
Hibernate.initialize(proxyObj);
- Isso implica um acoplamento relativamente alto ao DAO
- Embora possamos definir uma interface com
initialize
, outras implementações não têm garantia de fornecer qualquer equivalente.
- Adicione o comportamento da transação aos
Model
próprios objetos persistentes (usando proxy dinâmico ou@Transactional
)- Não tentei a abordagem de proxy dinâmico, embora nunca tenha parecido fazer o @Transactional funcionar nos próprios objetos persistentes. Provavelmente devido a essa hibernação é uma operação em um proxy para estar.
- Perda de controle quando as transações estão realmente ocorrendo
- Fornece API preguiçoso / não preguiçoso, por exemplo,
loadData()
eloadDataWithDeps()
- Força o aplicativo a saber quando empregar qual rotina, novamente o acoplamento forte
- Estouro de método,,
loadDataWithA()
....,loadDataWithX()
- Força a procura de dependências, por exemplo, fornecendo apenas
byId()
operações- Requer muitas rotinas não orientadas a objetos, por exemplo,,
findZzzById(zid)
e então emgetYyyIds(zid)
vez dez.getY()
- Pode ser útil buscar cada objeto em uma coleção, um por um, se houver uma grande sobrecarga de processamento entre as transações.
- Requer muitas rotinas não orientadas a objetos, por exemplo,,
- Faça parte da aplicação @Transactional em vez de apenas DAO
- Possíveis considerações de transações aninhadas
- Requer rotinas adaptadas para gerenciamento de transações (por exemplo, suficientemente pequeno)
- Pequeno impacto programático, embora possa resultar em grandes transações
- Fornecer ao DAO perfis de busca dinâmica , por exemplo,
loadData(id, fetchProfile);
- Os aplicativos devem saber qual perfil usar quando
- Tipo de transação AoP, por exemplo, interceptar operações e realizar transações quando necessário
- Requer manipulação de código de byte ou uso de proxy
- Perda de controle quando as transações são realizadas
- Magia negra, como sempre :)
Eu perdi alguma opção?
Qual é a sua abordagem preferida ao tentar minimizar o impacto dos lazy-loaded
relacionamentos no design de seu aplicativo?
(Oh, e desculpe por WoT )