Absolutely no idea

A blog by Lukas

Hibernate mappings and the XDoclet merge option

March 17th, 2009 by lukas

The project I’m currently working on uses XDoclet 1.2 to generate hibernate mapping and configuration files. Up to now, when our mapping requirements were too complex for XDoclet we would supplement our Java bean hibernate annotations with custom hbm.xml files and include those within an <otherMapping> element inside a <hibernatecfg> tag of the HibernateDocletTask.

Ant would then build most of the hbm.xml files from the bean annotations but also copy the handful of handcoded custom ones into the bin dir.

An improvement on this is to leave most of the hibernate annotations in the bean classes and have HibernateDoclet merge only the required mappings into the hibernate mapping files. The definition of the Hibernate XDoclet task is at thislink.

build.xml:

<target name="xdoclet-generate" depends="init" description="generate xdoclet hibernate mappings">
	   <!-- location of xdoclet libraries -->	
          <path id="xdoclet.task.classpath">
	        <fileset dir="${xdoclet.lib.dir}">
		     <include name="*.jar" />
	        </fileset>
	  </path>
 
	 <taskdef
            name="hibernatedoclet"
            classname="xdoclet.modules.hibernate.HibernateDocletTask"
            classpathref="xdoclet.task.classpath"
        />
 
	<hibernatedoclet  
		destdir="${build.classes.dir}"
		verbose="true">
 
                <!-- defines the files handled by xdoclet -->
                <fileset dir="${basedir}/src">
                    <include name="**/*.java"/>
                </fileset>
 
                <!-- generate the mapping files -->
		<hibernate 
			version="3.0"
			validateXML="true"
			mergeDir="${source.dir}"
		/>
 
		<!-- generate hibernate config file -->
		<hibernatecfg 
			destinationFile="hibernate.cfg.xml"				
			validateXML="true"
                        version="3.0"
			transactionManagerFactory="org.hibernate.transaction.CMTTransactionFactory"
			transactionManagerLookup="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup"
			dataSource="jdbc/schemaName"
			showSql="true"				
			dialect="org.hibernate.dialect.DB2Dialect"
                 >
			<otherProperty name="hibernate.transaction.flush_before_completion" value="true" />
			<otherProperty name="hibernate.transaction.auto_close_session" value="true" />
			<otherMapping name="resource" value="com/mycompany/domain/model/ComplexDomainObject.hbm.xml"/>
			<otherMapping name="resource" value="com/mycompany/domain/model/CommonDefinitions.hbm.xml"/>
		</hibernatecfg>		
        </hibernatedoclet>		
</target>

Notice how the above task defines a mergeDir at the hibernate element level. XDoclet will scan all dirs below this for any custom xml files to be merged into the hibernate mappings.

  • hibernate-properties.xml - goes into the root of the mergeDir. Anything in there is included in ALL mapping files.
  • hibernate-properties-{0}.xml - must be located in a directory underneath the mergeDir, mirroring the fully qualified package/name of the {0} bean class. (This is so that two classes from different packages could be mapped correctly).

I can now define any mapping not supported with annotations in 1.2 (e.g. a hibernate-filter) in a separate hibernate-properties-{0}.xml file:

hibernate-properties-NotSoSimpleDomainObject.xml:

    <filter name="limitByCurrentDataVersionFilter" condition=":dataVersion = dataversion"/>

and xdoclet will merge it into the mapping file at build:
NotSoSimpleDomainObject.hbm.xml:

<hibernate-mapping>
   <class name="com.mycompany.domain.model.NotSoSimpleDomainObject" table="NOT_SIMPLE_DOMAIN">
      <id name="id" column="NOT_SIMPLE_DOMAIN_ID">
         <generator class="identity">
         </generator>
      </id>
      <property name="codeValue" column="CODE_VALUE" />
      <property name="description" column="VALUE_DESC" />
 
      <filter name="limitByCurrentDataVersionFilter" condition=":dataVersion = dataversion"/>
 
   </class>
</hibernate-mapping>

For completeness sake, remember that you also need a filter definition inside a hibernate-mapping element (this is a global definition so can be anywhere - even in its own mapping file). I import this using the otherMapping element from a CommonDefinitions.hbm.xml in the Ant task above.

CommonDefinitions.hbm.xml:

<filter-def name="activatedFilter">
    <filter-param name="activatedParam" type="boolean"/>
</filter-def>

Posted in hibernate, programming | No Comments »

London - IT job market conditions & job hunting

December 30th, 2008 by lukas

Job hunting in London was quite different from other places where I have previously looked for a job. The market is huge, there are literally hundreds of companies looking for skilled developers and tens of recruitment agencies ranging from the “we do it all” to niche players who specialise in certain technologies, domains or methodologies (yep, there are companies who specialise in “Agile” :) I’d hazard a guess that there are hundreds - if not thousands - of job seekers in IT in London at the moment.

I have been told by various recruitment agents that 12 months ago the majority of the work was contract work but due to the economic crisis there has been a definite shift to permanent / full-time positions and up to 90% of current positions advertised in London are such. The few contract positions still around are mainly (surprisingly) in the investment finance sector - unavailable to most but the most hardcore (real-time Java, Swing, investment finance guru types).
Given the downturn, there are obviously also fewer permanent jobs going around but a few sectors are still hiring if not booming. Having spent about 2 months closely watching job ads and talking to recruiters I have observed a lot of activity in the following:

  • Banking / Finance - a lot of activity - even though thousands have been laid off, the mergers, consolidation & cost cutting initiatives all involve IT systems - many opportunities abound
  • E-Commerce - retailers are busy improving their on-line presence, upgrading web sites, adding new functionality (so they can shut physical stores to cut costs) - a lot of front-end & e-commerce work
  • Gambling / Gaming - there seems to be an enourmous amount of activity in this sector here in London at the moment - why do people tend to spend money they don’t have in a crisis?
  • Telecoms - most of the major telecoms providers seem to have some roles open at the moment. I found that they require high specialisation (i.e. pigeon-holing - sorry, we need somebody with Webwork and Apache CXF and not Spring MVC and Axis) and unless you match their spec exactly you’re unlikely to get an interview.

Having come from a more consulting type environment where every project used new / different technologies, I think the biggest pain was the focus on specialisation. I am assuming this is a result of such a big market. Several interviews I had focused on one or two technologies (e.g. Hibernate or Spring MVC) and if you didn’t know it to guru level then you’re out of luck, regardless of the fact that you’ve worked with a ton of similar technologies in the past. One of the most idiotic situations I had was when a recruitment agent invited me for a “chat” and then handed me a test consisting of 30 questions on the intricacies of Hibernate and Spring xml configuration syntax and told me his clients are looking for Hibernate and Spring professionals.

I used 3 websites to post my CV and look for positions:
http://www.jobserve.com - best interface & search, lots of jobs
http://www.jobsite.co.uk - ok interface & search, lots of jobs
http://www.cwjobs.co.uk - crap interface & very bad search functionality but contains lots of contract opportunities

There is also http://www.monster.co.uk but this site is badly organised, user unfriendly and has few IT opportunities compared to the others and apart from posting my CV on it I have not bothered with it.

Last minute tips:

  1. CV should be short and tailored to position - for the London market the CV should not be more than 4 pages!
  2. Refresh your knowledge - prepare before you start interviewing - if you haven’t coded in a while, fire up your IDE and write some code
  3. Once you start looking - be ready to be technically tested anytime
  4. Keep track of who you talk to and which companies you get forwarded to - with so many agents it’s very easy to have the same position presented by multiple agencies
  5. Figure out how far you want to commute - there are many large IT companies in Greater London or within 50km of London (e.g. Reading). Find out whether you are close to a rail link - the trains are more reliable than the tube. (It makes more sense to first find a job and then an apartment)
  6. Update your CV once a week and refresh it on the job sites - this way it will stay “current” on the site and more noticable to agents
  7. Follow-up all applications with a phone call - the recruiters get swamped by applications for every job - make yourself stand out from the crowd by having a conversation with them about the position
  8. Get a good internet connection - Initially I was able to cheaply share a FON connection but hotspots are few and far between in London. Unlike Canada there are very few coffee shops offering unlimited internet and you will usually have to pay for getting online as there aren’t many other options for when you’ve just arrived..

Looking for a job is a full-time job in itself so don’t get discouraged and let me know how it goes.
Good luck!

Posted in software development career | 2 Comments »

Back on-line from London!

December 30th, 2008 by lukas

First post since we’ve crossed the ocean to come and live and work in London. The timing was pretty dreadful - recession headlines everywhere, companies going bankrupt left right and centre and thousands of workers being laid off. All of this just added to the usual stresses associated with moving countries like finding an apartment, setting up bank accounts (arguably more difficult than finding a job in the current climate) and generally getting used to the new locality (I am still overwhelmed by how crowded London and Europe are).

The last few months have been tough and stressful - the move itself, getting used to London, getting used to how crowded Europe and London are, the job hunt, finding an apartment, getting a bank account, etc. No matter how many times you’ve been through it all it’s still a pain in the b..

It looks like we’re slowly settling in though. We have an apartment, we both landed great jobs and we’ve even had our first holiday over on the continent - snowboarding in Italy’s South Tyrol.

Bring on the New Year!

Posted in Uncategorized | No Comments »

Still on the road…

September 8th, 2008 by lukas

If you’re wondering why I haven’t posted in a while it’s because in the last two months I haven’t been near a computer long enough to write an email let alone put together a technical blog post.

Our stay in Vancouver has come to an end. My wife and I have decided not to extend our Canadian working holiday Visas and so have to finish our stay in North America. We have quit our jobs and are finally doing some traveling across this vast and beautiful continent. In the last couple of months we have been to some wonderful places - first to the far north, past the Arctic Circle to Yukon and Alaska and now we are finishing our road trip of the western US - from Vancouver, BC, through the Sunshine Coast, Vancouver Island, the states of Washington, Oregon, California, Nevada, Utah, Idaho, Wyoming and now Montana. We’re slowly making our way back to Vancouver where we’ll say good-bye to our friends and then get on a plane to Europe to start a new leg of our overseas adventure in October.

I haven’t gone, I’m still here, just busy doing something else that’s on my TODO list, that’s all. I’ll tick that off and I’ll be back soon enough. See you then.

Posted in holidays | No Comments »

WSDL to web service code in Weblogic 10

July 5th, 2008 by lukas

xml logoWeblogic 10 web services runtime uses JAX-WS and JAXB for web service generation. Following the preferred contract-first (or wsdl-first) design approach one can use the wsdlc Ant task to generate all web services artifacts (Impl file, proxy classes and java bean types and their xml serializers & deserializers) from a WSDL file and associated xsd schemas.

(Note: Before starting, make sure Weblogic 10 is correctly installed. Also, the web service generation relies on annotations so Java 5 must also be installed. Note that you need the JDK - not just the JRE - as the WSDL generation required tools.jar which comes with the JDK only)

WSDLC takes a WSDL file as parameter and uses custom JAXB binding files to configure the generation of Java files. Although this process is much more complicated than the simple package to namespace mapping file (NStoPkg.properties) used by Apache Axis it is also much more configurable. For example the JAXB binding files allow you to also specify things such as the name of the generated Impl file, names of operations, parameters as well as configure SOAP handlers. It’s basically a one-stop-shop for the configuration of the web service.

I use the JAXB binding files mainly to generate the the correct package structure of the various Java artifacts.

My WSDL and accompanying schema structure is something like this:

/JobMaintenanceService.wsdl                > defines services
/jobmaintenance/JobMaintenanceService.xsd  > defines main types used in the service
/enterprise_schemas/assignment/*.xsd   > defines types from the assignment functional area 
/enterprise_schemas/common/*.xsd       > defines various common types reused by all other schemas
etc..

It is important to note that JobMaintenanceService imports JobMaintenanceService.xsd which in turn imports other schemas which in turn may import or include other schemas as required. See my previous post on the difference between import vs. include.

The package structure I wanted from the above schemas was as follows:

com.mycompany.myapp.ws.client    > to hold service client classes - proxy, etc.
com.mycompany.myapp.ws.service   > to hold JobMaintenanceService impl class
com.mycompany.myapp.ws.dto       > to hold JobMaintenanceService schema files
com.mycompany.myapp.ws.types.assignment  > to hold types from the assignment schemas
com.mycompany.myapp.ws.types.common      > to hold types from common enterprise schemas
etc..

The following is the Ant target to generate the webservice code. The wsdlc ant task comes with Weblogic 10 (weblogic.wsee.tools.anttasks.WsdlcTask) and is actually a wrapper around Sun’s wsimport task so don’t be surprised if you get warnings or errors referring to wsimport.

build.xml:

<property name="bea.home" value="C:/apps/bea10" />
<property name="jdk.home" value="${bea.home}/jdk150_06" />
<property name="weblogic.home" value="${bea.home}/wlserver_10.0" />
<property name="src.dir" value="src"/>
<property name="wsdl.file.name" value="JobMaintenanceService"/>
 
<target name="run-wsdlc">
	<path id="compile.classpath">
		<fileset dir="${jdk.home}">
			<include name="lib/tools.jar" />
		</fileset>
		<fileset dir="${weblogic.home}">
			<include name="server/lib/weblogic.jar"/>
		</fileset>
	</path>
 
	<taskdef name="wsdlc" classname="weblogic.wsee.tools.anttasks.WsdlcTask" classpathref="compile.classpath" />
	<mkdir dir="${src.dir}"/>
 
	<property name="binding.declaration.file" value="schema-jobmaintenance.xjb,wsdl-jobmaintenance.xjb"/>
 
	<wsdlc
		type="JAXWS"
		srcWsdl="etc/job_maint/${wsdl.file.name}.wsdl"
		destJwsDir="${src.dir}/jws" 
		destImplDir="${src.dir}/impl" 
		explode="true" 
		failonerror="true"
	>
                <binding dir="etc" includes="${binding.declaration.file}"/>
		<classpath>
			<path refid="compile.classpath"/>
   		</classpath>
	</wsdlc>
</target>

The above will generate all required java files into the correct package structure. Here is an excerpt from the schemas binding file showing the mappings of the common and assignment namespaces.

schema-jobmaintenance.xjb:

<jxb:bindings
  version="1.0"
  xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
>
    <jxb:bindings
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      schemaLocation="job_maint/enterprise_schemas/common/Common.xsd" 
      node="/xs:schema"
    >
	<jxb:schemaBindings>
		<jxb:package name="com.mycompany.myapp.ws.types.common"/>
	</jxb:schemaBindings>
   </jxb:bindings>
 
   <jxb:bindings
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      schemaLocation="job_maint/enterprise_schemas/assignment/Assignment.xsd" 
      node="/xs:schema"
    >
	<jxb:schemaBindings>
		<jxb:package name="com.mycompany.myapp.ws.types.assignment"/>
	</jxb:schemaBindings>
   </jxb:bindings>  
....   
 
</jxb:bindings>

Some notes:

  • The wsdlc Ant task configures namespace to package mappings using custom JAXB binding files - schema-jobmaintenance.xjb and wsdl-jobmaintenance.xjb - one to map schema types and the other to map definitions from the wsdl.
  • Do NOT use the wsdlc option “packageName” in the Ant wsdlc task - this will override any custom bindings made in the jaxb config files.
  • Make sure you do NOT have Apache Axis and related jars in your classpath - they interfere with the weblogic ones from above and results in the binding files not being read!
  • I don’t think you can mix bindings for jaxws (for wsdl) and jaxb (for schema) in the same binding file - I spent quite a bit of time on it but could not get all my bindings to be read from a single binding file - if you know whether this is possible and how this is done please let me know!
  • I could not get nested bindings to work correctly for schemas (e.g. you’re supposed to be able to nest bindings for your imported schemas within bindings for the encompassing schema as in one of the example articles further below but that didn’t work for me - it seemed like the xpath expression with the namespace does not get evaluated correctly). I therefore created separate binding entries for each XSD of a particular namespace.
  • The only item I could NOT generate in it’s correct location was the JWS file (service Impl skeleton file). I tried many things but it just would not pick up the package from the binding file. I also stumbled on a WL10 support case that had this logged as an issue so maybe it is a true bug in this release of WL. Fortunately this is not too big of a deal as it is only a single file - and the one you have to manually edit anyway - to complete the web service implementation.
  • I recommend using an “copy” Ant task to only copy the *.java files into your src project structure as “wsdlc” automatically compiles the java src in the target directory:
    <copy todir="dest/dir">
        <fileset dir="${src.dir}">
            <exclude name="**/*.class"/>
        </fileset>
    </copy>

Finally here is a list of links I recommend to get more information on some of the above:

Wsdlc ant task reference on BEA’s Edocs website
Iterative Development of Weblogic 10 webservices from BEA

The following 2 awesome articles from dev2dev:
Using JAX-WS & JAXB with Weblogic 10
JAX-WS customization binding

Best of luck! If you have any questions or comments please feel free to post below.

Posted in xml, programming | No Comments »

« Previous Entries