This is a Hibernate question, but Eelco's 'class reloading' post
reminded me to ask on this list. I asked in the Hibernate forums, but
received no responses. Maybe someone here has a similar problem or some
thoughts/ideas.
* The Problem
Ok, so you have IoC where you inject services you want to use in other
services. Well basically I want to do something similar with my domain
model.
I have 3 different maven modules. (I have a lot more, but for
simplicity's sake)
1. user-module - Which contains a User.class with fields like
emailAddress, password, address information, etc.
2. accounting-module - which depends on user-module and need to keep
track of a user's pending account balance, posted balance, etc
3. mywebapp-module - which depends on accounting-module
Currently
If I want to get a user's account balance I have to
User user = userService.getUser("id");
UserBalance bal = accountingService.getBalance (user);
It gets very cumbersome trying to write a ton of different queries to
retrieve data from the different tables. For instance if I want to get
someone's account balance via their e-mail address a query exists in the
userService.findByEmailAddress(), but I have to write another method in
the accountingService to do this again.
* What Hibernate offers
1. Hibernate offers dynamic mode where you can persist fields via a
Map, but you have to set the mode on a 'per session' basis.
a. This solution could work if you could have POJO and DYNAMIC-MAP
in the same session. (which I don't see why this wouldn't be possible)
2. Hibernate offers dynamic components, but User.class has to know
about the dynamic components and they cannot be dynamically wired up.
* What I've been working on
Modules contributing fields to models of other modules.
Instead of UserBalance becoming its own class its now an interace that
'contributes' its fields (via getters/setters) to the User.class so I
can do this.
User user = userService.findByEmailAddress("[EMAIL PROTECTED]");
UserBalance balance = (UserBalance) user;
The only way I can think of to accomplish this is by creating new
classes via javassist/cglib.
1. I take User.class and see if there are any interfaces that want to
contribute their fields to User.class
2. I create a new class that extends User.class with the new fields,
User$Enhanced.class
3. Then for each class with a field User.class I replace it with the
newly generated class
There is one big downfall to this approach. You can't create classes via
the new operator.
User user = new User();
UserBalance balance = (UserBalance) user; <-- User does not implement
UserBalance, throwsClassCastException.
balance.setPending(0.0);
session.save(user); <-- Hibernate does not know about a User entity,
only the new User$Enhanced.class!
You have to create objects via a factory so the object is actually of
type User$Enhanced
User user = factory.create(User.class);
This is where class reloading would come in handy!
* Conclusion
I have not finished a prototype of this yet as there is a big learning
curve of (byte code engineering) playing with javassist.
I spent a whole day playing with this when I have other priorities, but
this could speed up development immensely.
Whoever read this, can you give me some feedback?
Think its a good idea?
Think a slippery slope of problems will unfurl once I get a prototype
running?
Are there any other existing solutions?
Thanks everyone!
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]