-->
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: Does UserType work inside of a component group?
PostPosted: Thu Sep 23, 2004 10:58 am 
Beginner
Beginner

Joined: Thu Feb 26, 2004 11:45 am
Posts: 46
Hibernate version: 2.12

Mapping documents:
<class name="com.trivin.bo.vehicle.Registration" table="REGISTRATION">
<!-- registrationID is generated/taken from associated Vehicle. Used registrationID -->
<!-- In reality, the registrationID "IS" the vehicleID. Registrations cannot live in absence of vehicle -->
<id name="registrationID" column="VehicleID">
<generator class="foreign">
<param name="property">vehicle</param>
</generator>
</id>
<discriminator column="JavaSource" type="string"/>
<property name = "productID" />
<one-to-one name="vehicle"
class="com.trivin.bo.vehicle.Vehicle"
constrained="true"
/>
<property name="plateState" />

<component name="plate" class="com.trivin.bo.inventory.Plate">
<property name="plateNumber" />
<property name="plateClass" type="trivin.test.persist.PlateClassUserType" column="plateClassCode"/>
<property name="plateSubClass" type="trivin.test.persist.PlateSubClassUserType" column="plateSubClassCode"/>
<property name="plateStyle" type="trivin.test.persist.PlateStyleUserType" column="plateStyleCode" />
</component>

<property name="plateType" />
<property name="expirationDate" />
<property name="grossWeight" />
<property name="unladenWeight" />
</class>

Code between sessionFactory.openSession() and session.close():
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
Vehicle veh = (Vehicle) session.get(Vehicle.class, new Long(id));
tx.commit();
session.close();

Full stack trace of any exception that occurs:

Name and version of the database you are using:
SQL 2000
The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:





I've placed an excerpt of a larger mapping file above, with the section of interest colored green. Basically, what i have is a Plate object inside of Registration. The Plate object contains other attributes. I'm limiting this to the PlateClass portion, since the other attributes below that are essentially the same pattern.

Example of real data might be:
PlateNumber: ABC123
PlateClassCode: COMM
...

So the data in the Registation Table would have those items.
I want to reconstruct Registration object properly when loading it form the DB.

It needs to contain a Plate Object that contains a string that is platenumber (no problem), but then it needs to get the PlateClassCode ("COMM" in this example) and with that code, i can fetch the appropriate PlateClass Object from our system and return /set it in the Plate Object.

The way i've attempted to implement this is to have Plate as a component containing PlateNumber and PlateClassCode etc. So far, so good. I then created my own UserType "trivin.test.persist.PlateClassUserType".

Still looking good. Below is the method inside my class that does, indeed, get called properly. I've properly indicated in the other required methods the type of object i'll be returning.

Code:
  public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException,
      SQLException {
    String name = rs.getString(names[0]);
    return rs.wasNull() ? null : getInvType(name, (BusinessObject) owner, getInvTypeType());


When i run the sample, "COMM" is passed properly, here, and i'm ready to pass back the appropriate PlateClass Object. I call a private method to do this. The trick, here, is that in order for me to fetch the object from our system, i also need the productID. The productID is part of Object owner. Indeed, it is present in nearly all of our business objects. You can see it in the above map.

And here's the rub, when i look at the "owner" object in the above code, it is Registration (as it should be). However, at this point in time, productID has not been loaded. In fact, nothing exists inside the owner object that is passed here.

Hibernate samples and documentation indicate that data should be present there. In fact, that is why owner is passed so that i have access to other information that would help me do my job (i think that was the intent). Are there conditions where this would not be the case?

Is it related to the fact that i'm doing this inside of a component? Could it be that components are handled 1st, then non-components which would mean that data outside of components is not yet available?

Of course this raises a the question as to what data is available when, in general, since i'm assuming there needs to be some ordering of how/when data is loaded into the objects.

Any help will be very much appreciated. We have this condition in many places in our system. We store codes, and then reconstruct immutable objects from these codes using productID.

thanks for any input on this.


Top
 Profile  
 
 Post subject: Help, please. Component/UserType limitation?
PostPosted: Fri Oct 01, 2004 12:05 pm 
Beginner
Beginner

Joined: Thu Feb 26, 2004 11:45 am
Posts: 46
I'm sort of really at roadblock here. Maybe my questions was too wordy, or didn't make sense.

Please, a simple answer to what i hope will be a very simple question. I can't get confirmation on this on either the documentation with the product, or "Hibernate in Action"

The question as simply i can put it is this.

Class PRegistration has Component Plate

Within Component Plate, i have defined a Custom User Type on one of the properties, plateNumber.

When:
Code:
  public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException,

is called on this property, the owner parameter is documented to contain essentially the PRegistration object above, to provide access to other useful information.

From what i can tell, the PRegistration is initialized, but never contains anything.

Below is a simple mapping with a few simple classes that reproduce this phenomena.

When a call into PlateUserType is made, the owner argument is an instance of PRegistration, but productID, and registrantName are empty. I really need productID.

Code:
<hibernate-mapping default-cascade="save-update">
     
        <class name="trivin.test.persist.composite.PRegistration" table="PREGISTRATION">
              <id name="registrationID" column="registrationID" type="long">
                      <generator class="identity"/>
              </id>
              <property name="registrantName" />
              <property name="productID" />
              <component name="plate"  >
                <property name="plateNumber" type="trivin.test.persist.composite.PlateUserType" column="plateNumber" />
                <property name="plateColor" column="plateColor" />
             </component>
        </class>
</hibernate-mapping>



So, am i to believe that the owner argument is irrelevant when passed to UserTypes within Components? Is this a known limitation?

I must have access to a single attribute in Class PRegistraion. It is the key to everyhing our application does.

Please, even if you confirm my worst suspicions, i can at least start looking for some alternative.

thanks again.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 01, 2004 3:00 pm 
Expert
Expert

Joined: Thu Jan 29, 2004 2:31 am
Posts: 362
Location: Switzerland, Bern
Well, this ist more a work around than a real solution, but maybe it helps:

Map PlateClassCode to a String property.
Instead of having the mapping to your class done in the user type, you could do the mapping in the Interceptor.onLoad() method and set the appropriate Object in an other property which is not managed by Hibernate.
For storing you would have to do this in the onSave and onFlushDirty methods.

HTH
Ernst


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 01, 2004 3:10 pm 
Beginner
Beginner

Joined: Thu Feb 26, 2004 11:45 am
Posts: 46
Quote:
Map PlateClassCode to a String property.
Instead of having the mapping to your class done in the user type, you could do the mapping in the Interceptor.onLoad() method and set the appropriate Object in an other property which is not managed by Hibernate.
For storing you would have to do this in the onSave and onFlushDirty methods.


I'm all for workarounds, thanks! The very key issue here is this. will i have access to the parent attribute. In the above simple case, will i have access to ProductID. In order for me to construct that plate type (and most of our objects) properly, i need to know what the ProductID is.

I will take a look at this, and i appreciate your suggestion.

I'll probably also take a look at Hibernate3 extended event support.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Oct 02, 2004 1:26 am 
Expert
Expert

Joined: Thu Jan 29, 2004 2:31 am
Posts: 362
Location: Switzerland, Bern
I'm not 100% sure if the onLoad is called for avalue type (i.e. components). If not it will be called for the owning entity which would be ok.

In the onLoad method you could check for the parent type with something like:

Code:
boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)  {
   if (entity instanceof ParentType) {
      doTheMapping();
      return true;
   }
}


HTH
Ernst


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.