【问题标题】:@SequenceGenerator - allocationSize, reverse engineering with Eclipse Hibernate Tools@SequenceGenerator -allocationSize,使用 Eclipse Hibernate 工具进行逆向工程
【发布时间】:2011-02-20 07:33:18
【问题描述】:

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

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

这导致以下注释:

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

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

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

是否可以在 hibernate.reveng.xml 中以某种方式进行设置?

【问题讨论】:

    标签: eclipse hibernate reverse-engineering hibernate-tools


    【解决方案1】:

    虽然没有像 Guillaume Husta 所说的那样得到官方支持,但我设法做了一个技巧,绕过了这个限制。而不是简单地说:

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

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

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

    【讨论】:

      【解决方案2】:

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

      Hibernate 帮助中心有文档。

      【讨论】:

        【解决方案3】:

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

        序列相关的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: 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

        在 JIRA (https://hibernate.atlassian.net/browse/HBX/) 中没有发现此问题的问题。

        【讨论】:

        • 已经用 Eclipse 中的搜索/替换为我解决了这个问题:搜索:@SequenceGenerator.*" replace: $0, allocationSize = 1
        • 这个答案对我最有帮助 - 它让我走上了正轨。我最终使用了一个自定义 POJOExporter 子类(使用 exporterclass 属性将 hbmtemplate ant 任务指向它)。然后定制了一些挂起的类,最后,框架调用了我自己的自定义 generateAnnIdGenerator() 方法,然后我只是破解了字符串来做我需要的事情。
        【解决方案4】:

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

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

        【讨论】:

        • 它使用类org.hibernate.id.SequenceGenerator,好像不是jpa
        【解决方案5】:

        您可以更新原始的 freemarker 模板以适应您的要求。 我们是这样做的:

        1) 向我们表的 reveng 条目添加一个“allocation-size-50”元属性:

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

        【讨论】:

          【解决方案6】:

          例如:

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

          :)

          【讨论】:

          • 好的,但这并不能解决“allocationSize”属性的初始问题?还是我错过了什么?
          • 对不起,我错了。我不得不使用 而不是序列来解决这个问题。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-03-13
          • 2014-11-07
          • 2012-03-15
          • 2016-05-22
          • 2021-05-14
          • 1970-01-01
          • 2012-03-10
          相关资源
          最近更新 更多