rey5137

Stars and mentions

Last 30 days, Oct 4 – Nov 2

GitHub stars2
mentions1
01234Oct 4Oct 18Nov 2
UTC days · repositories rey5137 owns1 repositories

Package downloads

No package download history available yet.

Top repositories

rey5137’s repositories ranked by new stars, as on trending.

Loading

Contributes to

Repositories outside rey5137’s account where rey5137 opened or reviewed pull requests in the past 365 days.

Who noticed rey5137

Everyone who starred or forked rey5137’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

2posts
Nov 31 post
  1. Hacker News · · rey5137 · rey5137/model-query

    Show HN: Model Query, declare a JPA DTO projection once, query it many ways

    1 point
  2. I got tired of JPA entity graphs, so I built Model Query Most JPA projects I've worked on hit the same wall on the read side. Writes through entities are fine. Reads are where it hurts: a list screen needs five columns and gets an entity graph, lazy proxies and the occasional N+1. Model Query is the library I built to fix that for myself. Version 0.5.0 is on Maven Central, and before I freeze the API at 1.0 I'd like it to be tried on real codebases. How I got here Plain JPA first. Entities model the schema well, but reading through them drags their relationships along. Every @ManyToOne has a fetch type, and controlling what a query actually loads turns into entity graphs, join fetch per query and watching the SQL log. DTO projections avoid that, but JPQL constructor expressions are strings, and Criteria multiselects are verbose and positional. Then Querydsl. Typed queries remove the strings. But the Q classes come from entities, so every query still writes its own joins and its own Projections.constructor(...). The DTO's shape lives in each query, not in one place. Then Blaze-Persistence. Entity Views solve the projection problem properly, and it's a powerful library. For me the cost was adoption: an extra runtime and integration layer, and one view interface per shape. The list screen, the detail screen and the export of the same table each got their own view, plus subviews for their joins. So I kept what worked in each: the entity mapping from JPA, generated typed constants from Querydsl, declared projections from Blaze. The projection is a plain record or class, and one model serves several shapes, because a query selects column sets of it instead of declaring a new view. What it looks like Here's a typical read before migration: a constructor expression and a query string that grows with each optional filter. var jpql = new StringBuilder("select new com.acme.OrderRow(o.id, o.status, o.total," + " c.name) from OrderEntity o left join o.customer c where 1 = 1"); status.ifPresent(s -> jpql.append(" and o.status = :status")); country.ifPresent(s -> jpql.append(" and c.country = :country")); jpql.append(" order by o.id"); var query = em.createQuery(jpql.toString(), OrderRow.class); status.ifPresent(s -> query.setParameter("status", s)); country.ifPresent(s -> query.setParameter("country", s)); return query.setMaxResults(100).getResultList(); With Model Query, the columns and the join move into a model, once: @QueryModel(root = OrderEntity.class) public class OrderView { @PrimaryKey private Long id; private String status; private BigDecimal total; @Join private Optional<CustomerView> customer = Optional.empty(); // getters and setters } @QueryModel(root = CustomerEntity.class) public record CustomerView(@PrimaryKey Long id, String name, String country) {} An annotation processor generates QOrderView. The joined model's columns become constants of the outer one (CUSTOMER_COUNTRY), and an empty Optional skips its filter, so the query has no branches: var query = QOrderView.query() .select(QOrderView.ALL.with(QOrderView.CUSTOMER)) .where(f -> f.eq(QOrderView.STATUS, status) .eq(QOrderView.CUSTOMER_COUNTRY, country)) .orderBy(QOrderView.ID.asc()) .build(); return executor.list(query, Limit.of(100)); The join is added only when CUSTOMER is selected. No entities are loaded: the query selects the model's columns into a Tuple and maps them, so the fetch type on the entity no longer decides what a read loads. (Both versions are in a test in the repo that checks they return the same rows for every filter combination.) What else is in 0.5.0 - Paging and export: list, page, count and stream, with offset, keyset and primary-key-first paging, plus large exports. - Children: to-many relations loaded through fetch plans, once per page in batches, not per row. - Selected fields: a @Selected SelectSet<Model> field tells an unselected column apart from a selected NULL, which is handy for PATCH-style APIs. - Writes (incubating): bulk update and delete driven by the same filters, inserts with returned keys and conflict clauses, and entity writes that still run your callbacks and audit listeners. - Vendors: H2, PostgreSQL and MySQL, behind an SPI. - Spring Boot starter: adds query methods to your existing Spring Data repositories, even with your own repository factory bean. It runs on Java 17+, Hibernate 6.6 and 7.x, and Spring Boot 3.4+, and it's tested on all of them in CI. When not to use it If you need CTEs, window functions or recursive queries everywhere, Blaze-Persistence (or jOOQ) is the better tool. If every query returns a different ad-hoc shape, Querydsl's per-query projections fit better. And Model Query is still 0.x: every public type is @Incubating until 1.0. There's a longer comparison in the docs. Try it The plain-JPA sample runs with one command from the repository root: ./mvnw -q -pl samples/plain-jpa -am package -DskipTests -Prun Or add it to your project: <dependency> <groupId>io.github.rey5137</groupId> <artifactId>model-query-jpa</artifactId> <version>0.5.0</version> </dependency> <dependency> <groupId>io.github.rey5137</groupId> <artifactId>model-query-annotations</artifactId> <version>0.5.0</version> </dependency> Then register model-query-processor in your compiler's annotation processor path. The getting started guide covers both plain JPA and Spring Boot. I'm looking for early adopters Before 1.0 freezes the API, I'd like to hear from people with real read-heavy JPA code: - Did the model fit your read paths, or where did it break? - What did you have to work around? - Which API names felt wrong? The feedback thread is here, and there are a few good first issues if you'd like to contribute. A star on GitHub helps too.

Trending awards, every completed day and week
Gold
01st place finishes
Silver
02nd place finishes
Bronze
03rd place finishes
Awarded repositories
0Owned by rey5137 now

No trending awards yet

None of the repositories rey5137 owns has finished in the top three of a completed trending day or week, by stars, forks or PR authors. See who is trending now.

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.