@SequenceGenerator - allocationSize, reverse engineering with Eclipse Hibernate Tools
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", sequ开发者_如何学PythonenceName = "SEQ_FOO_ID", allocationSize = 1)
Is it possible to set this somehow in the hibernate.reveng.xml?
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>
Yes, you can. You have to rewrite the strategy of the reveng class.
There is document in Hibernate help center.
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.
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>
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>
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>
:)
精彩评论