Why Feat Is Experimenting with a Zero‑Reflection ORM for the AOT Era
The article explores Feat's attempt to build a reflection‑free ORM that preserves MyBatis‑like developer experience by moving all mapping work to compile time, discusses the challenges posed by Java's AOT shift, and argues why such an experiment is both risky and worthwhile.
Java is entering the AOT era
In recent years many frameworks have embraced GraalVM Native Image, Spring AOT, Micronaut, and Quarkus to achieve faster startup, lower memory, and better cloud‑native experience.
Traditional Java frameworks rely heavily on runtime features such as reflection, dynamic proxies, and bytecode generation, which clash with the compile‑time orientation of Native Image.
Native Image prefers compile‑time determination, static analysis, and AOT processing rather than runtime discovery.
Java’s successful runtime‑centric designs are colliding with Native Image’s philosophy.
Why focus on ORM
Feat has already experimented with AOT for controllers and dependency injection, and now turns to database access, which involves object mapping, parameter binding, result‑set conversion, and metadata parsing—tasks that have historically depended on runtime mechanisms.
The question posed is whether the MyBatis development experience can be preserved while moving all of this work to compile‑time code generation.
Compile‑time implementation example
Developers still write the familiar MyBatis mapper interface:
@Mapper
public interface UserMapper {
@Select("""
select *
from user
where id = #{id}
""")
User selectById(long id);
}During compilation an annotation processor generates an implementation that uses plain JDBC without reflection or dynamic proxies:
public final class UserMapperImpl implements UserMapper {
@Override
public User selectById(long id) {
PreparedStatement ps = connection.prepareStatement(SQL);
ps.setLong(1, id);
ResultSet rs = ps.executeQuery();
User user = new User();
user.setId(rs.getLong(1));
user.setName(rs.getString(2));
return user;
}
}The whole process avoids reflection, dynamic proxies, runtime metadata, and extra Native Image configuration; all work is shifted to the compilation phase.
Do not use reflection
Do not use dynamic proxy
Do not depend on runtime metadata
No additional Native configuration required
All work is completed ahead of time during compilation.
Potential risks
The author admits the approach may fail because ORM touches many complex areas such as dynamic SQL, database dialects, type handlers, caching mechanisms, and plugin systems—features that MyBatis has refined over more than a decade.
The first stage of Feat ORM is simply to validate whether the technical route works, not to match MyBatis feature‑by‑feature.
Why it’s worth trying
Historically Java frameworks have tried to make the runtime smarter; Native Image invites a shift where the compiler takes on more responsibilities.
Will the compiler be able to shoulder more of the work?
If successful, the competitive edge may no longer be about having more runtime features but about moving work from runtime to compile time.
The author invites GraalVM users, Native Image practitioners, heavy MyBatis users, and AOT enthusiasts to discuss what an ORM should look like in the AOT era.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Three Knives
Every line of code you contribute to open source could help make the future better.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
