Gostei muito da sua ideia. Parabéns. Eu mesmo já tinha pensando em pegar a API de criteria do middlheaven e separá-la para poder usada “a vulso” como essa.
O que vc chama de “link de métodos” é "“encadeamento de métodos” (method channing). Link de métodos é outra coisa, é vc criar atalhos para métodos que são muito usados.
Fez muito bem usar a ideia dos metodos encadeados em vez dos métodos estáticos que o hhibernate usa. Mas tenha em mente que isso pode limitar a api.
Pelo que vi vc encadeia os métodos suponto “And” entre eles. Mas para uma API robusta vc precisa de OR também e poder mixar AND e OR. O Hibernate faz isso obrigado a criar objetos diferentes e realmente para uma api de métodos encadeados não é nada fácil (eu sei porque tenho esse problema na minha api que é mais generica que orm (pode ser usada para procurar texto com lucene) e a extenção de orm fica aqui)
Um detalhe é que a sua API apenas suporta jpa - pelo que entendi - isso é uma desvantagem. Se ela suportar hibernate normal (sem ser jpa) seria mais vantajoso.
PAra fazer isso separe a API de criteria do executor da criteria. Isso lhe vantagem para executar a mesma query contra várias fontes ( e mais tarde pode até fazer contra nosql). Idealmente teria uma classe/interface que o usuaário poderia implementar para suportar outras fontes de dados.
Em vez disto
EasyCriteria criteria = EasyCriteriaFactory.createQueryCriteria(getEntityManager(), Dog.class);
use isto
EasyCriteria criteria = EasyCriteriaBuilder.createQueryCriteria(Dog.class); // builder, não factory. O factory cria sozinho, o builder ajuda o programador a criar
EntityManagerExecutor executor = new EntityManagerExecutor (entitymanager);
// ou HibernateExecutor executor = new HibernateExecutor (session);
QueryResult result = executor .query(criteria);
Não é legal que o criteria tenha o getResultList() isto é um acoplamento desnecessário.
O EntityManagerExecutor vc pode usar injeção para colocar nas suas classes em vez do entitymanager direto e o efeito é o mesmo.
Para as restrições use as abreviações comuns como eq, lt, isNull, isEmpty, contains, starsWith, between, etc… não use equals para eq que dá problema com a nomenclatura padrão do java. Não use “with”, é um prefixo artificial que só alonga a escrita ( programadores de verdade não usam complete do IDE :twisted: )
Uma técnica que é util é ao encadear os métodos retornar um objeto diferente que tem só os métodos que podem ser usados naquele momento. Com isso vc consegue o agrupamento que vc falou. Ai poderia fazer algo como :
criteria.restrict("name").eq("Sergio").and("age").eq(18).or("age").eq(12).or('age").between(20, 30)
Repare que o restricte o and/or servem para dizer o nome do campo e o valor do operador vai junto dele.
quando vc usa restrict, and ou or, o retorno é um objeto que só tem os operadores. Desa forma o cara não pode fazer and(‘a’).and(‘b’) porque a api não deixa fazer isso por design.
quando o cara usa o operador, ai vc pode voltar ao objeto inicial antes de dar o restrict/and/or. Este mecanismo de method chaning do builder permite que a sua interface seja tão fluente quanto a sua imaginação deixar ( e a sintaxe do java deixar. tem coisas que dá um pouco de raiva não serem possíveis no java).
Não amarre a sua api à api do jpa e vc terá uma ferramente muitas vezes mais poderosa que pode ajudar as pessoas em operações de migração, na implementação correta do padrão Repositorio, e se Deus quiser, na extinção dos DAOs :lol: :lol: :lol:
Parabéns, continue que vai bem. Se precisa de ajuda , é só dizer.
A ideia é esta, na prática tem alguns truques necessários e uso pesado de generics. Dê uma olhada na minha api.