Java has JPA (Java Persistence API) which is an abstraction layer over various ORMs. However, most people use Hibernate. Hibernate is nice because it also gets out of the way when you need it to, like when you're inserting or selecting a massive amount of data. It also supports the Stream API now, which is super convenient.
I've found Admin interfaces on the same server to turn into liabilities and infosec in bigger orgs usually has strict rules around segregating admin access off into its own subnet with restricted access only to internal traffic.
That said, for simple monololiths I use Jhipster, which auto generates Admin pages for you similar to ActiveAdmin.
I recommend to not use an ORM. Really, with a modern language, an ORM is mostly redundant. If on Spring boot, simply use JDBCTemplate and TransactionTemplate to deal with raw SQL queries and transactionality. Get rid of all the annotation magic around this.
Then you need a bare minimum of mapping code. Mostly this boils down to a single line of code to call the relevant constructors while you extract columns from your rows in a type-safe way. Kotlin makes this stupidly easy. I'd argue this type of code is actually easier to maintain than misc annotation cruft all over your codebase. One way or another you end up expressing in some place that column foo is of type Int and goes into some property of a class MyLovelyFoo with a foo field. So MyLovelyFoo(foo=row.getInt("foo")) kind of does that in a really compact way and there's not a lot more to it. Of course Kotlin having default arguments, sane property handling, immutable data classes, etc. helps a lot. Mostly ORM made sense when people were doing JavaBeans on Java.
The problem with many Java persistance frameworks is the amount of magic that happens that leads to hard to understand bugs, sub optimal joins, and other stuff that just isn't worth having. A side effect of using an ORM is also overengineered table structures because people are pretending they are doing OO and thus end up with way to many tables and columns, fragile and more frequent migrations, and a lot of silly joins. This magnifies all of the above problems.
If you know what you are doing, you can actually fix this of course and do it properly even while using an ORM like hibernate. At this point you lose most of the advantages of using an ORM because now you are knee deep into framework complexity and trying to coerce it to do the right thing while spending disproportionate amounts of time inspecting and guiding all the magic it does for you. I've been parachuted in more than a few hibernate projects gone bad. The fix is always pruning back all the copy paste annotation magic propagated by juniors, vastly cutting down on the number of model classes, use of inheritance and the silly hacks that come with that, fixing the transactionality, etc.
I have dynamically generated queries that span over 200 lines. Doing this without a query builder is pure madness. It doesn't matter how modern your language is, manually concatenating SQL shouldn't happen in 2019.
100% this. Whenever folks recommend simpler options like JDBI, I have to shake my head. Rolling your own query builder with string templates feels like an SQL injection attack waiting to happen. If you know 100% going into a project that you won't have to modify the structure of your queries based on user input, then it's an acceptable option. But it's quite common, at the very least, to have user input that results in variable number of terms in where clauses.
Hibernate is quite powerful and the tooling in IntelliJ (or Eclipse) catches many common mistakes at edit time. Where most folks get themselves into trouble is with all the caching setup. Not surprising, but if you want to just use Hibernate as a cache-less mapper there's always the StatelessSession interface.
I also don't get the oft-repeated notion that ORMs result in bad table design. You can map any tables you can dream up. And if you insist on doing inheritance, Hibernate has 4 different strategies for mapping to classes. Certainly one of those has the performance characteristics you're looking for.
Do those queries need to be that long or is that just a limitation of your ORM tool and the table structure it generated so you can pretend to have an object database? I've simplified quite a few domain models to fit the querying needs and gotten rid of lots of tables, joins, etc. in the process. There's no wrong or right here but my observation with ORM is that it leads to needlessly complicated table designs, which in turn makes querying the database needlessly hard.
Often long queries with convoluted joins are a good sign something is wrong with your table layout. ORM lets you get away with some bad design but it always catches up with you eventually.
If you're going this way I would still recommend a library like jOOQ.
It gets out of the way and is very low-level, but it still allows you to build type-safe SQL instead of having to randomly concatenate strings in order to build your query.
This is especially useful if you have dynamic joins and things like that, which can get hairy fast if you're building them manually.
+1 for jOOQ. I prefer to Just Write Queries than muck about with quirky ORM magic that gets turned into queries. jOOQ lets me do that with safe query building and type checking through to the DB level (with code gen).
I've found Admin interfaces on the same server to turn into liabilities and infosec in bigger orgs usually has strict rules around segregating admin access off into its own subnet with restricted access only to internal traffic.
That said, for simple monololiths I use Jhipster, which auto generates Admin pages for you similar to ActiveAdmin.