Por que colocar uma camada DAO em uma camada de persistência (como JDO ou Hibernate)

Data Access Objects (DAOs) são um padrão de design comum e recomendado pela Sun. Mas os exemplos mais antigos de DAOs Java interagiam diretamente com bancos de dados relacionais - eles estavam, em essência, fazendo mapeamento relacional de objeto (ORM). Hoje em dia, vejo DAOs em cima de frameworks ORM maduros como JDO e Hibernate, e me pergunto se isso é realmente uma boa ideia.

Estou desenvolvendo um serviço da web usando JDO como camada de persistência e estou pensando em introduzir ou não DAOs. Eu prevejo um problema ao lidar com uma classe particular que contém um mapa de outros objetos:

public class Book {
    // Book description in various languages, indexed by ISO language codes
    private Map<String,BookDescription> descriptions;
}

JDO é inteligente o bastante para mapear isso para uma restrição de chave estrangeira entre as tabelas "BOOKS" e "BOOKDESCRIPTIONS". Ele transparentemente carrega os objetos BookDescription (usando o carregamento lento, acredito), e os persiste quando o objeto Book é persistido.

Se eu introduzisse uma "camada de acesso a dados" e escrevesse uma classe como BookDao, e encapsulasse todo o código JDO dentro dela, então o carregamento transparente dos objetos-filhos desta JDO não estaria contornando a camada de acesso a dados? Por consistência, todos os objetos BookDescription não devem ser carregados e mantidos por algum objeto BookDescriptionDao (ou método BookDao.loadDescription)? Ainda assim, a refatoração tornaria a manipulação do modelo desnecessariamente complicada.

Então, minha pergunta é: o que há de errado em chamar JDO (ou Hibernate, ou qualquer ORM que você queira) diretamente na camada de negócios? Sua sintaxe já é bastante concisa e é agnóstica ao armazenamento de dados. Qual é a vantagem, se houver, de encapsulá-lo no Data Access Objects?

questionAnswers(10)

yourAnswerToTheQuestion