2

I use the Eclipse Hibernate Tools to create domain classes with JPA annotations from my Oracle database. To control sequence generation I have added the following entry to the hibernate.reveng.xml:

...
<primary-key>
<generator class="sequence">
<param name="sequence">SEQ_FOO_ID</param>
</generator>
</primary-key>
...

This results in the following annotation:

@SequenceGenerator(name = "generator", sequenceName = "SEQ_FOO_ID")

However I need to set the "allocationSize" like this:

@SequenceGenerator(name = "generator", sequenceName = "SEQ_FOO_ID", allocationSize = 1)

Is it possible to set this somehow in the hibernate.reveng.xml?

Spooky
  • 65
  • 3
  • 10

6 Answers6

3

although it is not officially supported as says Guillaume Husta, I managed to do a trick so bypass this limitation. Instead of simply put:

 <param name="sequence">MYSEQ</param>

You may notice tha the generator only appends quotes (") at start and end, so you can do something similar done in sql injection, you only need another parameter of the jpa annotation that ends the quote even its not really used, for example the parameter "schema"

   <param name="sequence">MYSEQ", allocationSize = 1, schema="MYSCHEME</param>
Jesus M C
  • 341
  • 2
  • 8
2

Yes, you can. You have to rewrite the strategy of the reveng class.

There is document in Hibernate help center.

meadlai
  • 895
  • 1
  • 9
  • 22
1

It doesn't seem to be possible in the current version of Hibernate Tools (4.3.1.CR1) in 2014 !

The sequence related JPA annotations are generated by the method generateAnnIdGenerator() in class EntityPOJOClass.
Code in GitHub : https://github.com/hibernate/hibernate-tools/blob/master/src/java/org/hibernate/tool/hbm2x/pojo/EntityPOJOClass.java#L252

Extract of source code (generateAnnIdGenerator()) :
builder.resetAnnotation( importType("javax.persistence.SequenceGenerator") ) .addQuotedAttribute( "name", "generator" ) // TODO: shouldn't this be unique, e.g. entityName + sequenceName (or just sequencename) ? .addQuotedAttribute( "sequenceName", properties.getProperty( org.hibernate.id.SequenceGenerator.SEQUENCE, null ) ); // TODO HA does not support initialValue and allocationSize

No issues found in JIRA (https://hibernate.atlassian.net/browse/HBX/) for this problem.

Guillaume Husta
  • 4,049
  • 33
  • 40
  • Have solved this for me with search/replace in Eclipse: search: @SequenceGenerator.*" replace: $0, allocationSize = 1 – Spooky Sep 11 '14 at 09:19
  • This answer was most helpful to me - it set me on the right track. I ended up using a custom POJOExporter subclass (pointed the hbmtemplate ant task at it with the exporterclass attribute). Then customised a few classes that hang off so that, finally, the framework was calling my own custom generateAnnIdGenerator() method, then I just hacked up the string to do what I need. – Shorn Aug 05 '15 at 04:19
1

Maybe late but the correct config is:

<hibernate-reverse-engineering>
    <schema-selection match-schema="SchemaName" />
    <table-filter match-name=".*"></table-filter>
    <table name="TableName">
        <primary-key>
            <generator class="org.hibernate.id.SequenceGenerator">
                <param name="sequence">SequenceName</param>
            </generator>
            <key-column name="ColumnName" />
        </primary-key>
    </table>
</hibernate-reverse-engineering>
1

You can update the originial freemarker templates to adapt to your requirements. We did it as follows:

1) add an "allocation-size-50" meta attribute to our table's reveng entry:

<table name="Checklisteneintrag" >
    <meta attribute="allocation-size-50"/>
    <primary-key>
        <generator class="sequence">
            <param name="sequence_name">Checklisteneintrag_Seq</param>
        </generator>
    </primary-key>
</table>

2) get the original "Ejb3PropertyGetAnnotation.ftl" and adapt it to start with the following code:

<#if ejb3>
<#if pojo.hasIdentifierProperty()>
    <#if property.equals(clazz.identifierProperty)>
        <#if pojo.hasMetaAttribute("allocation-size-50")>
            ${pojo.generateAnnIdGenerator()?replace('@SequenceGenerator(', '@SequenceGenerator(allocationSize=50, initialValue=1, ')}
        </#if>
        <#if !pojo.hasMetaAttribute("allocation-size-50")>
            ${pojo.generateAnnIdGenerator()?replace('@SequenceGenerator(', '@SequenceGenerator(allocationSize=1, initialValue=1, ')}
        </#if>
    </#if>
</#if>
....

3) put all ftl files (the original ones and the one that was adapted) into a directory that can be found by reverse engineering, e.g. in maven we reference the templatepath="src/hibernate/resources/templates" as follows:

        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution> <!-- set MAVEN_OPTS="-Dfile.encoding=UTF-8" && mvn antrun:run@hbm2java -->
                    <id>hbm2java</id>
                    <phase>none</phase>
                    <configuration>
                        <target>
                            <echo message="Start generating entities .." />
                            <taskdef name="hibernatetool" classname="org.hibernate.tool.ant.HibernateToolTask" />
                            <hibernatetool templatepath="src/hibernate/resources/templates">
                                <classpath>
                                    <path location="${project.build.directory}/classes" />
                                    <path location="${project.basedir}/src/hibernate/resources" />
                                </classpath>
                                <!-- Note that configurationfile does not work anymore in Hibernate 
                                    5.4.0 -->
                                <jdbcconfiguration propertyfile="src/hibernate/resources/hibernate.properties" revengfile="src/hibernate/resources/hibernate.reveng.xml" reversestrategy="at.rsg.lp.flow.hibernate.FlowRevEngStrategy" packagename="at.rsg.lp.flow.services.jpa.model" detectmanytomany="true" />
                                <!-- jdbcconfiguration configurationfile="src/hibernate/resources/hibernate.cfg.xml"
                                    revengfile="src/hibernate/resources/hibernate.reveng.xml" reversestrategy="at.rsg.lp.flow.hibernate.FlowRevEngStrategy"
                                    packagename="at.rsg.lp.flow.services.impl.jpa" detectmanytomany="true"
                                    / -->
                                <hbm2java destdir="src/main/java" jdk5="true" ejb3="true" />
                            </hibernatetool>
                            <echo message="End generating entities" />
                        </target>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
stefan.m
  • 1,912
  • 4
  • 20
  • 36
0

For example:

<hibernate-reverse-engineering>
    <schema-selection match-schema="SchemaName" />
    <table-filter match-name=".*"></table-filter>
    <table name="TableName">
        <primary-key>
            <generator class="sequence">
                <param name="sequence">SequenceName</param>
            </generator>
            <key-column name="ColumnName" />
        </primary-key>
    </table>
</hibernate-reverse-engineering>

:)

David
  • 1
  • 1
    Ok, but this doesn't solve the initial problem with the "allocationSize" attribute? Or do I miss something? – Spooky Apr 20 '11 at 06:45
  • sorry, i was wrong. I had to use instead of sequence to solve that problem. – David Apr 20 '11 at 12:54