Do package locations in ebean.mf support wildcards?

219 views
Skip to first unread message

vladimir.p...@tealium.com

unread,
Mar 5, 2019, 9:52:57 PM3/5/19
to Ebean ORM
Is there support for wildcards when specifying package paths in ebean.mf? If not, is that something worth adding?

Example of ebean.mf with wildcards (could speed up classpath scan & enhancement on a large codebase):

entity-packages: com.mystuff.*.ebean.entity
transactional
-packages: com.mystuff.*.ebean.transactional
querybean
-packages: com.mystuff.*.ebean.query

Compared to only specifying top level package, which can be more classpath scan intensive.

entity-packages: com.mystuff
transactional
-packages: com.mystuff
querybean
-packages: com.mystuff


Rob Bygrave

unread,
Mar 5, 2019, 11:06:12 PM3/5/19
to ebean@googlegroups
> Is there support for wildcards when specifying package paths in ebean.mf? 

No there isn't.


> If not, is that something worth adding?

Well, it is very unlikely to hurt but I think becomes ...

- We can specify multiple packages (comma delimited list of packages)
- 99% of people are using build time enhancement so the benefit is largely wrt build time (this is not about classpath scanning on startup at runtime - use config.addClass() to avoid that)

Regarding the patterns for packages it is typically:

entity-packages: typically points to packages that only contains entities, finders and query beans
transactional-packages: points to packages that are "the service layer"
querybean-packages: for Java typically points to the same packages as transactional-packages
querybean-packages: for Kotlin typically points to the same packages as entity-packages


So I think this becomes, where are all the packages containing @Transactional annotations and query bean use (what I'd call the "service layer code").  

Is using the below worthwhile?
transactional-packages: com.mystuff.*.service

Do we get a good build time improve using the wildcard for transactional-packages on a large code base? 

It is very unlikely to hurt adding wildcard support.


Cheers, Rob.


--

---
You received this message because you are subscribed to the Google Groups "Ebean ORM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ebean+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

vladimir.p...@tealium.com

unread,
Mar 7, 2019, 4:08:54 PM3/7/19
to Ebean ORM
Regarding the patterns for packages it is typically:
transactional-packages: points to packages that are "the service layer"

Good point. Package space "com.mystuff.*.service" is more realistic and makes more sense than "com.mystuff.*.ebean.transactional".

Do we get a good build time improve using the wildcard for transactional-packages on a large code base?

I tried it out on our codebase and so far the answer seems to be no. Afraid to even use the word benchmark (since it is not), but on Macbook 2.2GHz i7 16GB Memory and codebase of 6K+ Java classes with 600K+ lines, IntelliJ Rebuild Project took on average 1 min, while Maven Build (No Tests) took about 3 min. There was no noticeable performance difference between specifying "com.mystuff.*" vs "com.mystuff.mymodule.myservice.*".

Maybe an argument could be made that wildcards could bring some additional readability to the config file?

- We can specify multiple packages (comma delimited list of packages)

I'm trying to avoid having to specify multiple packages in ebean.mf. The reason is primarily driven by our development process.

Example of how we usually try to structure our code:

> com
   
> mystuff
            > mymodule
                         > featureA // Developer Mike is working on this
                                 > service // may use QueryBeans
                                 > entity // contains Ebean Entities
                         > featureB // Developer Emily is working on this
                                 > service // can contain QueryBeans
                                 > entity // contains EbeanEntities

Above grouping tries to keep features as self contained as possible. Looking at "com.mystuff.mymodule.featureA.*" should tell a complete story of how it is implemented. Developer doesn't have to look in other packages.

If Mike works on featureA and Emily works on featureB in parallel (separate Git Pull Requests), then I would like them to avoid having to modify ebean.mf. That's why right now I'm leaning towards casting a wide net with "com.mystuff.*" in ebean.mf. It helps avoid potential merge conflicts. It's also one less thing Emily & Mike need to worry about. They use Entities & Query Beans in their feature package and things just work.

The initial question about wildcards came from that line of thinking. I also stumbled across this article (Section: Do not use wild car class path scanning), which made me wonder if perhaps "com.mystuff.*.service.*" would be better than "com.mystuff.*".

Rob Bygrave

unread,
Mar 7, 2019, 6:10:56 PM3/7/19
to ebean@googlegroups
> If Mike works on featureA and Emily works on... leaning towards casting a wide net with "com.mystuff.*" in ebean.mf. It helps avoid potential merge conflicts.

This by itself probably justifies adding wildcards.  I'm on board with that.


> Example of how we usually try to structure our code:

Yes. The issue wrt entities in particular is that they tend have relationships that cross feature boundaries.  The nice feature separation isn't always so easy when it comes to entities with relationship and DB referential integrity. 

I see myself as having different mindsets for Feature/API design vs Entity/DB design.  I like to get into a mindset that can view the DB/Entity design as a whole (relationships, cardinality, optionality, normalisation, types).  I don't tend to think of an entity as being "owned" by a single feature but you could if you say "write separation" - an entity is only written/persisted by a single feature.  

So for myself I tend to have feature separate on API's (Rest API + service layer) but then group the "domain" together so that I can more easily see that the domain model makes sense as a whole.  That would mean Mike and Emily must talk to each other for domain changes but I tend to see that as a good thing.  The success of this is dependent on getting "enough" of the domain model  (DB design) correct and agreed to "early enough".  If we do that well then normalisation suggests we should only get additive non breaking changes to the domain model - Mike wants to add something to the domain model to support Feature A ... and he can - no problem (because we are just extended a good normalised db design). 

Just my personal thoughts on it anyway. 


Cheers, Rob.

vladimir.p...@tealium.com

unread,
Mar 15, 2019, 2:47:47 PM3/15/19
to Ebean ORM
> This by itself probably justifies adding wildcards.  I'm on board with that.

Awesome!

> The nice feature separation isn't always so easy when it comes to entities with relationship and DB referential integrity. 

Very true. Above package example is a bit simplified. It becomes more involved over time. Sub-modules/packages with entities and then X number of features/services that use them within. This grouping is not perfect and can certainly have some ugly & unintuitive edge cases, but tends (at least in my experience so far) to help more than hurt.

> mindset that can view the DB/Entity design as a whole

Perhaps I have fallen into an anti-pattern over the years, but when it comes to seeing DB design as a whole I usually turn to DB/SQL tools directly. It's easier to study a SQL schema and a diagram drawn from it, rather than looking at application code entities. If entities end up sprinkled across various packages and become "owned" by features/modules, it's okay in my opinion because underlying database will always show the full picture.

My two cents. Let me know if you think there are better ways and approaches. Feedback is always appreciated. :) 
Reply all
Reply to author
Forward
0 new messages