Flex Pasta » 2009 » May
Ever run into the problem with Hibernate where a child collection needs to be filtered? With Flex, most child collections are going to be fetched eagerly. These child collections may need to filtered based on some filter to the parent. I found this problem to be a little tricky. If anyone has a better solution, commentary is welcome.
Take the following object model for example. A Cat class contains a collection of “kittens”. Let’s say that the Cat class has a “color” property on it and I want to pull all Cats whose color is white. In HQL, I would write something like “from Cats where color = ‘white’”. This would get me a collection of all white Cats, which would contain a collection of each of the Cat’s kittens. Now consider that I want to filter the kittens to only get kittens whose color is also white. The entire kittens collection is always filled in each Cat class, with no HQL join query that can filter the kittens collection.
Here is how you can filter the Cat’s kittens by using the Hibernate Criteria api.
Criteria c = this.getSession().createCriteria(Cat.class)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.add(Restrictions.eq(”color”, “white”))
.createCriteria(”kittens”, Criteria.LEFT_JOIN)
.add(Restrictions.eq(”color”, “white”))
;
List<Cat> cats = c.list();
This is not what I would say is ideal for getting what I want, but it worked. Hope it helps you.
I’m kind of into automation. If I have to do something more than a few times a day, it needs to be automated to work for me. I originally wanted to write a flexpasta.bat file that would just write this post and code it for me, but that seemed a bit overboard.
One thing most web developers encounter in a day is testing their code. This usually involves reloading the page each time a code change in made and published. With Flex, we are having to reload the whole app, then probably make a bunch of clicks to get to the part of the application we are testing. This has become a pain, especially when making nit picky UI changes. Which brings me to the automation part. What if, when we make changes to code, it automatically reloads the flex module I am working on so that I can see the changes right away with no reload/type/click action? Making UI changes would be so much nicer.
To do this I have created DynamicModuleLoader.as. Basically, it extends ModuleLoader. Every 5 seconds it will ping the server to find out if the module has changed. If it has changed, it dumps the old module and loads the new one. Works best with two monitors. Just stating the obvious, but this is not for a production environment! Just helps for development.
package com.flexpasta.modules
{
import flash.display.DisplayObject;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.utils.Timer;
import mx.modules.Module;
import mx.modules.ModuleLoader;
public class DynamicModuleLoader extends ModuleLoader
{
public function DynamicModuleLoader()
{
super();
}
private var timer:Timer = new Timer(5000,50000);
override public function addChild(child:DisplayObject):DisplayObject
{
var disp:DisplayObject = super.addChild(child);
if(child is Module && !timer.running)
{
timer.addEventListener(TimerEvent.TIMER, checkForNewModule);
timer.start();
}
return disp;
}
private function checkForNewModule(event:TimerEvent):void
{
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, httpResult);
var urlReq:URLRequest = new URLRequest(url);
urlLoader.load(urlReq);
}
private var byteAmount:Number
private function httpResult(event:Event):void
{
if(isNaN(byteAmount))
{
byteAmount = event.currentTarget.bytesTotal;
}
else if(byteAmount!=event.currentTarget.bytesTotal)
{
byteAmount = event.currentTarget.bytesTotal;
unloadModule();
loadModule(url);
}
}
}
}