[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-dev] Typesafe fluent query DSL library donation to Eclipse project?


Might add motivation for donating is because of the widespread use of tet string JPQL/HQL/SQL native/CriteriaBuilder in Java code and this interface is arguably easier and safer to use.
Thus if I open sourced on my own and it gained traction and became a much used library, I would feel responsible for spending a lot of my spare time maintaining it.

I would of course help out maintaining after donation, proper code and design doc etc, it is just not that fun to take on that responsibility alone for something that is up to now a private hobby project .

Regards,
Nils Henrik Lorentzen


On Wed, May 22, 2019 at 5:56 PM Nils Henrik Lorentzen <nils.lorentzen@xxxxxxxxx> wrote:
Hi,

I have filed a draft for an eclipse proposal for a hobby project that I might donate to eclipse, it is typesafe queries like QueryDSL or jOOQ but without the need for any code generation, just add library to maven and start using right away.
Example queries below.
Supports most of JPQL but should do subselects, update and delete. Latter should have some code reuse from select.Â

Queries can be pre-built, ie. static and then parameterized at query time, conceptually like named query.

Existing JPA users can start using it right away, just pass EntityManager and query resuts are managed objects as usual, if querying entities. Column queries are mapped to POJO fields by library.

Is this of interest? Would this if accepted as a project sort under Eclipselink project? Seems like the most appropriate place at first look.
Sent a mail to Eclipse Management Organisation about draft too but haven't heard anything yet.

Also plan to do tree transform of results, if technically feasible ala pseudocode

select.tree(map column1, 2, 3 to one POJO type on distinct column 1, map column 4, 5, 6 to sub POJO list for each of first POJOs)

where can map a tree of POJOs out of the result columns from a joined SQL result by looking at the distinct columns. Could perhaps also select into hashmaps if wanted to convert straight to JSON without intermediate DTOs but might encourage bad coding practices, skipping data access tier and call DB straight from REST service implementations.Â

possibly also support NoSQL document database (eg. without join possibiity) and search server (Elasticsearch, Solr) queries, can already create native SQL queries from built model instead of JPQL.

"from" is missing as keyword here, it is deduced from the entity types involved, not sure if always will work but less to type :) Used to have that so could re-add "from" if necessary.

Farm and LandPlot are JPA entities, FarmInfo is just a POJO for collecting returned rows and columns.

Somewhat peculiar syntax with having to utilize javabean getters with "get" prefix but advantage is as mentioned no code generation necessary. If java had real field references as a language feature, it would be nicer (something like field<Integer> hectares = LandPlot::hectares)

final MultiBuilt<Farm> query
        = select.list(Farm.class)
            .leftJoin(Farm::getLandPlots)
            .where(LandPlot::getHectares).isGreaterThan(new BigDecimal("40.04"))
            .build();


Aliased. Builder interfaces allow a query to have only types (by table name if was SQL) or only aliases, for syntax consistency, types are more type safe since alias uses java.util.Supplier for fields)



    final Farm   f = select.alias(Farm.class);
    final LandPlot l = select.alias(LandPlot.class);
ÂÂ Â Â Â
    final MultiBuilt<Farm> query
        = select.list(f)
            .leftJoin(f::getLandPlots, l)
            .where(l::getHectares).isGreaterThan(new BigDecimal("40.04"))
            .build();

Advanced example, mapping single rows to POJO fields in typesafe manner.

Â
ÂMultiBuilt<FarmInfo> query = select.list(FarmInfo.class)
                .map(Farm::getFarmId).to(FarmInfo::setFarmId)
                .map(Farm::getSubFarmId).to(FarmInfo::setSubFarmId)
            .where(Farm::getSubFarmId).isEqualTo("sub2")
            .and(Farm::getFarmId).endsWith("3")
            .groupBy(Farm::getFarmId).and(Farm::getSubFarmId)
            .having(Farm::getFarmId).contains("oth").and(Farm::getFarmId).contains("er")
            .orderBy(Farm::getFarmId).desc().and(Farm::getSubFarmId)
           ÂÂ.build();Â

Regards,
Nils Henrik Lorentzen
Â