@SequenceGenerator - AllocationSize,使用 Eclipse Hibernate Tools 进行逆向工程

发布于 2024-09-01 23:47:26 字数 531 浏览 5 评论 0原文

我使用 Eclipse Hibernate Tools 从 Oracle 数据库创建带有 JPA 注释的域类。为了控制序列生成,我在 hibernate.reveng.xml 中添加了以下条目:

...
<主键>
<生成器类=“序列”>
<参数名称=“序列”>SEQ_FOO_ID


...

这会产生以下注释:

@SequenceGenerator(名称 = "生成器", 序列名称 = "SEQ_FOO_ID")

但是我需要像这样设置“allocationSize”:

@SequenceGenerator(名称=“生成器”,序列名称=“SEQ_FOO_ID”,allocationSize = 1) 是否

可以在 hibernate.reveng.xml 中以某种方式设置它?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

追我者格杀勿论 2024-09-08 23:47:26

尽管正如 Guillaume Husta 所说,它没有得到官方支持,但我设法做了一个技巧,绕过了这个限制。而不是简单地说:

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

您可能会注意到生成器仅在开始和结束处附加引号(“),因此您可以在sql注入中执行类似的操作,您只需要jpa注释的另一个参数来结束引号,即使它不是真的使用,例如参数“schema”

   <param name="sequence">MYSEQ", allocationSize = 1, schema="MYSCHEME</param>

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>
朮生 2024-09-08 23:47:26

是的,你可以。
你必须重写复仇类的策略。

Hibernate帮助中心有文档。

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

There is document in Hibernate help center.

温馨耳语 2024-09-08 23:47:26

在当前版本的 Hibernate Tools 中似乎不可能(4.3.1.CR1) 在 2014 年!

序列相关的 JPA 注释由 EntityPOJOClass 类中的 generateAnnIdGenerator() 方法生成。
GitHub 中的代码: https://github.com/hibernate/hibernate-tools/blob/master/src/java/org/hibernate/tool/hbm2x/pojo/EntityPOJOClass.java#L252

源代码摘录(generateAnnIdGenerator ()) :
<代码>
builder.resetAnnotation( importType("javax.persistence.SequenceGenerator") )
.addQuotedAttribute( "name", "generator" ) // TODO:这不应该是唯一的,例如entityName + sequenceName(或者只是sequencename)?
.addQuotedAttribute( "sequenceName", properties.getProperty( org.hibernate.id.SequenceGenerator.SEQUENCE, null ) );
// TODO HA不支持initialValue和allocationSize

JIRA 中未发现问题(https://hibernate.atlassian.net/browse/HBX/ )针对这个问题。

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.

ㄖ落Θ余辉 2024-09-08 23:47:26

也许晚了但正确的配置是:

<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>

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>
画骨成沙 2024-09-08 23:47:26

您可以更新原始的 freemarker 模板以适应您的要求。
我们按如下方式进行操作:

1) 将“allocation-size-50”元属性添加到表的 reveng 条目中:

<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) 获取原始的“Ejb3PropertyGetAnnotation.ftl”并将其调整为以以下代码开头:

<#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) 将所有 ftl文件(原始文件和改编后的文件)放入可以通过逆向工程找到的目录中,例如在 Maven 中,我们引用 templatepath="src/hibernate/resources/templates" ,如下所示:

        <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>

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>
不知在何时 2024-09-08 23:47:26

例如:

<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>

:)

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>

:)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文