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.  [ 2 posts ] 
Author Message
 Post subject: Hibernate breaks Template Method pattern?
PostPosted: Fri Oct 07, 2005 7:16 am 
Newbie

Joined: Fri Oct 07, 2005 6:36 am
Posts: 7
Hello there,

I'm rather new to Hibernate (and absolutely to the forums here) but I already spent a lot of time on it and a major application is already running powered by Hibernate - but I'm experiencing some error that I cannot seem to be able to solve without changing my application's model classes.

You can find the mapping document and some code below. But first the problem description (with symbolic class names):

I use the Template Method Pattern in some classes. An abstract base B class defines a template method and within this method it calls some abstract method that tells it how to behave, in my case: whether to do a certain check or not and in case it does the checking there could be an exception thrown.

So I have 2 subclasses X and Y of this abstract base class and furthermore one of those 2 classes is a subclass of the other (Y subclass of X; you can see that easily from the code and mapping documents).

Now what happens: I call the template method for subclass Y but the Hibernate CGLIB proxy seems to be subclassing class X and so breaks my code because subclass X defines a different implementation of the abstract method than Y!

At least that is what I see in the stack trace.

Do you have ideas how I could fix this without code changes? Or is there even something wrong with my code?

I know that I could use some other pattern than Template Method (like Strategy), but I think that would be a bit clumsy in the code.

I'd appreciate some help =)

Kind regards,
Denis


Hibernate version: hibernate-3.0

Mapping documents:
Code:
<hibernate-mapping>
   <class name="xxx.model.impl.PopulationImpl"
      table="ageofpirates.population" discriminator-value="1">
      <id name="populationId" type="integer">
         <column name="population_id" />
         <generator class="native" />
      </id>
      <discriminator column="discr" type="integer" />
      <version name="version" column="version" />

... some properties ...

      <subclass
         name="xxx.model.impl.AnotherPopulationImpl"
         discriminator-value="2" />
   </class>
</hibernate-mapping>



Code between sessionFactory.openSession() and session.close():
Code:
public abstract class ItemMapping
{
   ...

    /**
     * Implement this method to achieve checked or unchecked behaviour.
     *
     * @return true if checking should be done.
     */
    protected abstract boolean doItemLimitChecking();

    /**
     * The template method.
     */
    protected final void addItemsUnmapped(String itemType, int num)
    {
   ...

        if (doItemLimitChecking())
        {
            // do something that might throw an exception
       ...
        }

   ...
    }

   
   ...
}

---------

public class PopulationImpl extends ItemMapping implements Population
{
   ...

    public void transferTo(Map<String, Integer> m, Population target)
    {
        for (String key : m.keySet())
        {
            subtract(key, m.get(key));
            target.add(key, m.get(key));
        }
    }

    public void add(String type, Integer num)
    {
        super.addItemsUnmapped(type, num);
    }

   ...

    @Override
    protected boolean doItemLimitChecking()
    {
        return true;
    }
}

------------

public class AnotherPopulationImpl extends PopulationImpl
{
    @Override
    protected boolean doItemLimitChecking()
    {
        return false;
    }
}


Full stack trace of any exception that occurs:
Code:
at xxx.model.util.ItemMapping.doCheck(ItemMapping.java:126)
        at xxx.model.util.ItemMapping.addItemsUnmapped(ItemMapping.java:69)
        at xxx.model.impl.PopulationImpl.add(PopulationImpl.java:121)
        at xxx.model.impl.PopulationImpl$$FastClassByCGLIB$$48c488b6.invoke(<generated>)
        at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
        at org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:137)
        at xxx.model.impl.PopulationImpl$$EnhancerByCGLIB$$8fb3f49f.add(<generated>)
        at xxx.model.impl.PopulationImpl.transferTo(PopulationImpl.java:101)
        at xxx.model.impl.PopulationImpl$$FastClassByCGLIB$$48c488b6.invoke(<generated>)
        at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
        at org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:137)
        at xxx.model.impl.IslePopulationImpl$$EnhancerByCGLIB$$477c785a.transferTo(<generated>)
        at xxx.model.Isle.removeCaptainFromShip(Isle.java:831)
        at xxx.model.Isle$$FastClassByCGLIB$$283125a8.invoke(<generated>)
        at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
        at org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:137)
        at xxx.model.Isle$$EnhancerByCGLIB$$392133e1.removeCaptainFromShip(<generated>)
        at xxx.business.sf.impl.GameSessionFacadeImpl.removeCaptainFromShip(GameSessionFacadeImpl.java:893)


Name and version of the database you are using: that's unimportant

The generated SQL (show_sql=true): nothing to do with generated SQL

Debug level Hibernate log excerpt: nothing interesting there


Top
 Profile  
 
 Post subject: More Information Needed...
PostPosted: Fri Oct 07, 2005 9:53 am 
Newbie

Joined: Sun Aug 28, 2005 2:13 pm
Posts: 9
Please show some failure reproducing code:

    * where you create an object of the derived type
    * print the result of the doItemChecking method
    * save and commit that object,
    * clear the session an retrieve it again
    * print the result of the doItemChecking method
[/list]


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 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:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.