-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Extending a legacy persistent class and its mapping file
PostPosted: Tue Apr 29, 2008 11:39 pm 
Newbie

Joined: Tue Apr 29, 2008 1:11 pm
Posts: 4
Just started using Hibernate. I have a strange requirement (I think!) that I can't seem to be able to solve. I have a legacy application using Hibernate that I need to customize.

Class "C1" is mapped to Table "T1" and both of them can NOT be modified. Class "C1" is being used by the legacy bussiness layer.
So, I would like to write a class "C2" that extends class "C1" and add a new attribute. It would mean adding a <set> of <composite-element> in the hibernate mapping file. The collection should resolve to table "T2".


// Existing mapping
<class name="C1" table="T1">
...
</class>

// The new class I wrote
class C2 extends C1 {
Set addresses;
//... has getAddresses and setAddresses
}

What I am hoping for is a construct in the mapping file to say,
<class name="C2" extends="C1">
<set name="addresses" table="T2"> ... </set>
</class>

My concern is: How do I ensure that the existing code continues to work with class "C1" and the new code works with both class "C1" and class "C2" at the same time?
Ideally: Is there a way to tell Hibernate to transparently return "C2" ALL the time even from the methods in the existing code that were returning instances of "C1" ?
I am not sure if what am I asking for even makes sense.

Please help!

Thanks
A lost new user!


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 01, 2008 12:40 pm 
Expert
Expert

Joined: Fri Oct 28, 2005 5:38 pm
Posts: 390
Location: Cedarburg, WI
We faced the same problem, but on a much bigger scale. Our base product can be customized by our custom services department, and by our customers. We created a plugin architecture to deal with this, both for entities and all other types used by the application.

We ship a DLL with base product entities and embedded mapping files. These classes and mapping files are not directly modified. Instead, entity subclasses and corresponding new mapping files are defined. The subclasses extend the base product entities, but the corresponding mapping files completely replace the base ones (since I'm not aware of how to "extend" a mapping definition). The entity subclasses must be in a different namespace, and must have the same class names as the entities they extend.

When our application starts up and initializes the NHibernate configuration object, it searches through the entity assemblies in reverse order of how they override each other, adding resources for individual mappings if the unqualified class name's mapping has not yet been added.

This way, at runtime, NHibernate returns instances of the overriden types, and HQL queries work as expected whether or not replacement plugin entity types are defined. We also use a factory class to create all new transient instances, and this factory checks the NHibernate mappings (we keep the NHibernate configuration object around so we can look up this info) to determine the correct plugin entity type to instantiate.

Note that taking this plugin approach for entities across the board throughout the application prevents subclassing entities for polymorphism. We do not use polymorphic entities though, so this restriction is not a problem for us.


Top
 Profile  
 
 Post subject: Extending a legacy persistent class and its mapping file
PostPosted: Tue May 06, 2008 2:38 pm 
Newbie

Joined: Tue Apr 29, 2008 1:11 pm
Posts: 4
Thanks Nels_P_Olsen.

I wasn't "watching" this forum, because I accidentally posted it here. I had posted the same question on the Hibernate (Java) forum and watching that but got no replies yet. But now, I am glad that accident took place.

My problem is similar to yours, (not as big though and you are right) but the difference is that I am customizing code that was provided where as in your case, you are providing code that is customizable - if I understood correctly, you implemented a mechanism to override the base mappings and to create new transient instances. I wish my legacy code had those. :(

The legacy code I am working with has service classes which use the persistence classes in HQL and "new" statements. Right now, I am having to extend the persistence classes and ALL the legacy service classes that depend/use those persistence classes. Is there a better way to do this?

Thanks
-Jay


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 07, 2008 10:33 am 
Expert
Expert

Joined: Fri Oct 28, 2005 5:38 pm
Posts: 390
Location: Cedarburg, WI
If you really require existing entity classes to remain unmodified, and only use your subclass extension in new situations, then the cleanest possible way I can think of still requires that all calls to
Code:
new SomeEntity()

get changed to something like
Code:
EntityFactory.CreateInstance<SomeEntity>()


However, since you now own and can directly modify all of the legacy code you're extending (is this the case?), and if the entity classes you need to extend apply to all existing uses, then can you just modify the legacy entity classes directly to add additional properties? Then the entity types remain the same, and very little if any legacy code needs modification.

We had to create our plugin infrastructure because our custom services department and our customers will not be modifying the base product's code, only replacing compiled types with subclasses. This is not so much for intellectual property reasons as it is for making it possible for the base product to be updated by just dropping in new DLLs. When they replace an entity class with an extended one, they're telling the system that they want their replacement used everywhere. The entity factory is needed because they can't change existing compiled code that refers to the unextended entity type, and that base code needs to magically get and use their extended type without realizing it.


Top
 Profile  
 
 Post subject: Extending a legacy persistent class and its mapping file
PostPosted: Fri May 16, 2008 10:08 am 
Newbie

Joined: Tue Apr 29, 2008 1:11 pm
Posts: 4
Thank you Nels_P_Olsen.

I can not modify the legacy persistent classes or the service classes. The solution I have employed for now is to extend the legacy persistence classes and ALL the legacy service classes that "new" (create instances of) those persistence classes.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.