How can I extend Java code generated by JAXB, CXF or Hibernate tools?

13,383

Solution 1

For JAXB, see Adding Behaviours.

Basically, you configure JAXB to return a custom instance of the object you'd normally expect. In the below example you create a new object PersonEx which extends the JAXB object Person. This mechanism works well in that you're deriving from the generated classes, and not altering the JAXB classes or schemas at all.

package org.acme.foo.impl;

class PersonEx extends Person {
  @Override
  public void setName(String name) {
    if(name.length()<3) throw new IllegalArgumentException();
    super.setName(name);
  }
}

@XmlRegistry
class ObjectFactoryEx extends ObjectFactory {
  @Override
  Person createPerson() {
    return new PersonEx();
  }
}

Note that the @Override directive is important in case your JAXB object changes - it will prevent your customisation becoming orphaned.

Solution 2

As for Hibernate you may tweak the template files used in code generation to change their behaviour. If you want to tweak the HIbernate Tools you can edit, for example: dao/daohome.ftl

You may even add fields to the "toString()" output editing the .hbm.xml files

...
<property name="note" type="string">
    <meta attribute="use-in-tostring">true</meta>
    <column name="note" />
</property>
...

Both for logging and validation you may consider using AOP with AspectJ (I don't recommend messing with the generated code, since you might want to build that from scratch many times over).

Solution 3

First I would reiterate that modification of generated code has many problems associated with it and that, where possible it should be avoided. That said sometimes this is impractical to avoid or more effort than just dealing with the changes when the code is regenerated.

Sadly java doesn't support the concept of partial classes that c# has. These are precisely to solve this sort of problem.

You should see if your code generation tools support some form of meaningful comments which delimit regions added by yourself in the class (this is unlikely and won't help if you are modifying the code rather than adding to it)

You best option if you really wish to do this is to generate the files initially but check them into a version control repository immediately. Then make your changes, check that in.

Next time you rerun the tools and let them overwrite the existing files you can diff against your source controlled ones and merge the changes back in (most trivial changes like addition of new columns/tables will be little effort.

This will not help you as much if the code generator suddenly generates radically different code (say a new version) but in those cases any code you added which wasn't simply additional convenience methods relying on data/methods already exposed publicly) will have problems no matter how it is mixed into the class. The version control system does still help however since it also records the original changes so you can see what you had added previously and what, one would assume, you need to recreate in the new style.

Solution 4

The way I have used Hibernate is to generate base classes that I then extend. I add all my business logic (if any) to these subclasses. I quite often also end up changing the FreeMarker templates used by Hibernate to further customize the generated classes.

Solution 5

It is not a good idea to edit generated code files, either by editing the files them selves or by subclassing. Whatever you do, be sure to leave the signature created by the tool intact, so that it will be possible to understand in the future that the file was auto-generated.

I recommend that you research the command options of the tools to see if they allow you some flexibility. Some tools can generate abstract classes or interfaces instead of concrete classes. If this is not possible, create a domain object that includes the autogenerated object as a member variable.

Share:
13,383
mjn
Author by

mjn

Software developer for Delphi and the Java platform, SCJP, SCJA

Updated on June 03, 2022

Comments

  • mjn
    mjn about 2 years

    With generated Java source code, like

    • code generated with Hibernate tools
    • code generated with JAXB schema binding (xjc)
    • code generated with WDSL2Java (cxf)

    all generated classes are "value object" types, without business logic. And if I add methods to the generated source code, I will loose these methods if I repeat the source code generation.

    Do these Java code generation tools offer ways to "extend" the generated code?

    For example,

    • to override the ToString method (for logging)
    • to implement the visitor pattern (for data analysis / validation)