如何在HyperJaxb3 Cxf项目中将现有Id设置为主键(从wsdl生成代码)?

时间:2015-03-18 15:09:46

标签: java wsdl cxf primary-key hyperjaxb

我正在尝试将主键重新定义为现有ID,但是使用wsdl文件生成Apache CXF插件。 wsdl文件在这里 - https://api.mindbodyonline.com/0_5/ClientService.asmx?wsdl

我的pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>MindBodyCXF</groupId>
  <artifactId>CXFSpring</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>CXFSpring Maven Webapp</name>
  <url>http://maven.apache.org</url>
    <properties>
        <cxf.version>2.5.6</cxf.version>
        <hibernate-jpa-2.1-api.version>1.0.0.Final</hibernate-jpa-2.1-api.version>
        <hibernate-entitymanager.version>4.3.8.Final</hibernate-entitymanager.version>
        <hyperjaxb3-ejb.version>0.5.5</hyperjaxb3-ejb.version>
        <hsqldb.version>2.3.2</hsqldb.version>
        <hibernate.maven.plugin.version>2.2</hibernate.maven.plugin.version>
    </properties>
    <dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>

        <!-- Apache CXF -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-beans</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-context</artifactId>
                </exclusion>

            </exclusions>

        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-web</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-databinding-jaxb</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>${hibernate-jpa-2.1-api.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate-entitymanager.version}</version>
        </dependency>
        <!-- Hyperjaxb3 -->
        <dependency>
            <groupId>org.jvnet.hyperjaxb3</groupId>
            <artifactId>hyperjaxb3-ejb-runtime</artifactId>
            <version>${hyperjaxb3-ejb.version}</version>
        </dependency>
        <!-- HSQLDB -->
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>${hsqldb.version}</version>
            <scope>runtime</scope>
        </dependency>

        <!--PostgresSQL-->
        <dependency>
            <groupId>postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.1-901.jdbc4</version>
        </dependency>
        <!-- Logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.1</version>
        </dependency>

        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
            <exclusions>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>logkit</groupId>
                    <artifactId>logkit</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>avalon-framework</groupId>
                    <artifactId>avalon-framework</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- Testing -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>3.0.1.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hisrc.hifaces20</groupId>
            <artifactId>hifaces20-testing</artifactId>
            <version>0.1.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-core</artifactId>
            <version>3.0.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-client</artifactId>
            <version>3.0.4</version>
        </dependency>
        <!--String processing-->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>18.0</version>
        </dependency>
        <dependency>
            <groupId>org.jadira.usertype</groupId>
            <artifactId>usertype.core</artifactId>
            <version>3.0.0.CR1</version>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.7</version>
        </dependency>


    </dependencies>
    <build>
        <finalName>MindBodyCXF</finalName>
        <plugins>
            <!--hibernate plugin for ddl creation-->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>hibernate3-maven-plugin</artifactId>
                <version>${hibernate.maven.plugin.version}</version>
                <executions>
                    <execution>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>hbm2ddl</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <components>
                        <component>
                            <name>hbm2ddl</name>
                            <implementation>jpaconfiguration</implementation>
                            <outputDirectory>src/main/resources/hbm2ddl</outputDirectory>
                        </component>
                    </components>
                    <componentProperties>
                        <persistenceunit>integration.mindbody</persistenceunit>
                        <propertyfile>src/test/resources/persistence.properties</propertyfile>
                        <outputfilename>schema.ddl</outputfilename>

                        <drop>true</drop>
                        <create>true</create>
                        <export>true</export>
                        <format>true</format>
                    </componentProperties>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>postgresql</groupId>
                        <artifactId>postgresql</artifactId>
                        <version>9.1-901.jdbc4</version>
                    </dependency>
                </dependencies>
            </plugin>

            <!--cxf plugin for wsdl 2 java-->
            <plugin>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-codegen-plugin</artifactId>
                <version>${cxf.version}</version>
                <executions>
                    <execution>
                        <id>generate-sources</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>wsdl2java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <sourceRoot>${project.build.sourceDirectory}</sourceRoot>
                   
                    <wsdlOptions>
                        <wsdlOption>
                           
                            <wsdl>${basedir}/src/main/wsdl/ClientService.xml</wsdl>

                           
                            <bindingFiles>
                                <!-- JAX-WS bindings -->
                                <bindingFile>${basedir}/src/main/wsdl/binding.xml</bindingFile>
                               
                            </bindingFiles>
                            <extraargs>
                                <!-- Turns on the hashCode plugin -->
                                <extraarg>-xjc-XhashCode</extraarg>
                                <!-- Turns on the equals plugin -->
                                <extraarg>-xjc-Xequals</extraarg>
                                <extraarg>-xjc-XtoString</extraarg>
                                <!-- Turns on the Hyperjaxb3 EJB plugin -->
                                <extraarg>-xjc-Xhyperjaxb3-ejb</extraarg>
                                <!--<extraarg>-xjc-Xinheritance</extraarg>-->
                                <extraarg>-xjc-XfixJAXB1058</extraarg>
                                <extraarg>-xjc-enableIntrospection</extraarg>
                                <extraarg>-impl</extraarg>
                                <!--<extraarg>-verbose</extraarg>-->

                            </extraargs>
                        </wsdlOption>
                    </wsdlOptions>

                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.jvnet.jaxb2_commons</groupId>
                        <artifactId>jaxb2-basics</artifactId>
                        <version>0.9.3</version>
                    </dependency>
                    <dependency>
                        <groupId>org.jvnet.hyperjaxb3</groupId>
                        <artifactId>hyperjaxb3-ejb-plugin</artifactId>
                        <version>${hyperjaxb3-ejb.version}</version>

                    </dependency>
                </dependencies>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
        <!--to allow hbm generation-->
        <resources>
            <resource>
                <directory>src/main/wsdl</directory>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>META-INF/persistence.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

我的binding.xml在这里 -

<jaxws:bindings

        xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
        xmlns:s="http://www.w3.org/2001/XMLSchema"
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
        xmlns:hj="http://hyperjaxb3.jvnet.org/ejb/schemas/customizations"
        xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
        jaxb:extensionBindingPrefixes="xjc hj orm"
        xmlns:test="urn:test">



    <jaxws:bindings node="wsdl:definitions/wsdl:types/s:schema" >
        <jaxb:globalBindings generateElementProperty="false" localScoping="toplevel" generateIsSetMethod="false" >
            <jaxb:javaType name="java.util.Date" xmlType="s:dateTime"
                           parseMethod="org.apache.cxf.tools.common.DataTypeAdapter.parseDateTime"
                           printMethod="org.apache.cxf.tools.common.DataTypeAdapter.printDateTime" />
            <jaxb:javaType name="java.util.Date" xmlType="s:date"
                           parseMethod="org.apache.cxf.tools.common.DataTypeAdapter.parseDate"
                           printMethod="org.apache.cxf.tools.common.DataTypeAdapter.printDate" />
            <jaxb:serializable uid="1"/>
        </jaxb:globalBindings>
        <jaxws:enableWrapperStyle>
            false
        </jaxws:enableWrapperStyle>
        <hj:persistence>
            <hj:default-one-to-many fetch="EAGER"/>

        </hj:persistence>

        <jaxb:bindings node="s:complexType/s:complexContent/s:extension/s:sequence/s:element[@name='Description']">
            <hj:basic>
                <orm:column length="2500"/>
            </hj:basic>
        </jaxb:bindings>
        <jaxb:bindings node="s:complexType/s:complexContent/s:extension/s:sequence/s:element[@name='Bio']">
            <hj:basic>
                <orm:column length="750"/>
            </hj:basic>
        </jaxb:bindings>
        <jaxb:bindings node="s:complexType/s:complexContent/s:extension/s:sequence/s:element[@name='ID']">
        <hj:id/>
    </jaxb:bindings>


    </jaxws:bindings>
</jaxws:bindings>

但选择的ID未转换为@Id。

如何更改我的binding.xml以进行转换?

回答Aleksei 1评论:

我添加了更多一般请求以涵盖所有需要的ID并通过FindPath Mozilla Extension验证所有结果 - 仅选择了所需的元素 `

<jaxb:bindings node="//s:element[@name='ID']">
            <hj:id/>
        </jaxb:bindings>

`

生成了类,但是当我运行'mvn process-classes'时,我收到了一个错误:

Caused by: org.hibernate.AnnotationException: Unable to define/override @Id(s) on a subclass: integration.mindbody.Appointment

我认为抛出在ArrayOfAppointment中生成Hjid和在约会中生成Id;

ArrayOfAppointment.java: `

 @Id
    @Column(name = "HJID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getHjid() {
        return hjid;
    }

`

Appointment.java:
`

 @Id
    @Column(name = "ID", scale = 0)
    public Long getID() {
        return id;
    }

`

I have such annotations in several places:
` 

 @ManyToOne(targetEntity = SessionType.class, cascade = {
        CascadeType.ALL
    })
    @JoinColumns({
        @JoinColumn(name = "SESSIONTYPE_APPOINTMENT_ID"),
        @JoinColumn(name = "SESSIONTYPE_APPOINTMENT_HJID")
    })
    public SessionType getSessionType() {
        return sessionType;
    }

`

I think this is the reason of an exception.

All code is available here - [bitbucket repository][1] https://bitbucket.org/sergiishapoval/mindbodyintegrationtestproject/src/179b133cf3a730c718de329c694b311347e16984/?at=mindbodyPrototype 

完整堆栈跟踪 -

Execution default of goal org.codehaus.mojo:hibernate3-maven-plugin:2.2:hbm2ddl failed: [PersistenceUnit: integration.mindbody] Unable to c
onfigure EntityManagerFactory
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:224)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:120)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:347)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:154)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:582)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:158)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution default of goal org.codehaus.mojo:hibernate3-maven-plugin:2.2:hbm2ddl failed: [Pe
rsistenceUnit: integration.mindbody] Unable to configure EntityManagerFactory
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:143)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
        ... 19 more
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: integration.mindbody] Unable to configure EntityManagerFactory
        at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:265)
        at org.codehaus.mojo.hibernate3.configuration.JPAComponentConfiguration.createConfiguration(JPAComponentConfiguration.java:28)
        at org.codehaus.mojo.hibernate3.configuration.AbstractComponentConfiguration.getConfiguration(AbstractComponentConfiguration.java:51)
        at org.codehaus.mojo.hibernate3.exporter.Hbm2DDLExporterMojo.doExecute(Hbm2DDLExporterMojo.java:87)
        at org.codehaus.mojo.hibernate3.HibernateExporterMojo.execute(HibernateExporterMojo.java:152)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132)
        ... 20 more
Caused by: org.hibernate.AnnotationException: Unable to define/override @Id(s) on a subclass: integration.mindbody.Appointment
        at org.hibernate.cfg.AnnotationBinder.bindId(AnnotationBinder.java:1860)
        at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1279)
        at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:754)
        at org.hibernate.cfg.AnnotationConfiguration.processArtifactsOfType(AnnotationConfiguration.java:546)
        at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:291)
        at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1148)
        at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1226)
        at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:173)
        at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:854)
        at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:191)
        at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:253)
        ... 25 more

1 个答案:

答案 0 :(得分:2)

这实际上应该可行,这里one example from tests

理论:

  • 根本不应用自定义。
  • hj:id适用于错误的ID。您似乎有几个与XPath表达式匹配的元素。尝试更具体,即将复杂类型的名称添加到XPath表达式。
  • 您有nillable="true"。也许你得到了一个额外的包装器属性(ID可能是由JAXBContext<Long>引起的nillable。因此,您实际上可能需要自定义生成的属性。这里是an example

查看生成的代码可能会提供更多提示,请考虑发布。

披露:我是Hyperjaxb3的作者。

Update

我刚刚成功mvn clean install

问题是您的XPath //s:element[@name='ID']会选择多个ID元素,而不只是一个。{1}}元素。它实际上选择了模式中的所有ID元素。

这与从其他复杂类型继承的复杂类型(例如,MBObject)发生冲突。父compex类型已经有id(自动生成)但你的自定义指向无论如何都要使用ID元素作为id。这会导致问题。看起来HJ3试图生成一个复杂的id(通过@IdClass),但这在Hibernate中失败了。

修复不是覆盖子类中的id属性。这可以通过两种方式实现:

  • 仅自定义非子类中的ID元素(在根类中)。
  • 使用hj:mapped-subclass自定义父类。

我选择了最后一个解决方案,并将MBObjectScheduleItem映射到了超类:

https://github.com/highsource/hyperjaxb3-support/blob/master/m/MindBody/src/main/wsdl/binding.xml#L60-L65

因此像Appointment这样的类(在JPA意义上)成为层次结构的根,并且id自定义正常工作(映射的supperclasses没有id)。所以我得到了一个成功的构建(数据库测试失败但不打破构建)。