问题
I am trying to redifine primary key to existing IDs, but with Apache CXF plugin generation from wsdl file. wsdl file is here - https://api.mindbodyonline.com/0_5/ClientService.asmx?wsdl
my 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>
My binding.xml is here -
<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>
but chosen IDs wasn't converted to @Id.
How I can change my binding.xml to convert it?
Answer to Aleksei 1 comment:
I have added more general request to cover all needed IDs and validate all results through FindPath Mozilla Extension - only needed element was chosen `
<jaxb:bindings node="//s:element[@name='ID']">
<hj:id/>
</jaxb:bindings>
`
Classes was generated, but when I run 'mvn process-classes' I have received an error:
Caused by: org.hibernate.AnnotationException: Unable to define/override @Id(s) on a subclass: integration.mindbody.Appointment
I think It is thrown do to generated Hjid in ArrayOfAppointment and Id in Appointment;
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
full stack trace -
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:
This should actually work, here's one example from tests.
Theories:
- Customizations are not applied at all.
hj:id
is applied to the wrongID
. You seem to have several elements matching the XPath expression. Try to be more specific i.e. add the name of the complex type to the XPath expression.- You have
nillable="true"
. Maybe you get an additional wrapper property generated (ID
may be aJAXBContext<Long>
due tonillable
). So you may actually need to customize the generated property. Here's an example.
Seeing the generated code may give more hints, consider posting it.
Disclosure: I'm the author of Hyperjaxb3.
Update
I've just got a successful mvn clean install
.
The problem is that your XPath //s:element[@name='ID']
selects several ID
elements, not just one. It actually selects all the ID
elements in the schema.
This collides with complex types which inherit from other complex types (for instance, MBObject
). Parent compex types already have ids (automatically generated) but your customization points to use the ID
element as id anyway. This causes problems. Looks like HJ3 tries to generate a complex id (via @IdClass
) but this fails in Hibernate.
The fix is not to override id property in subclasses. This can be achieved in two ways:
- Only customize
ID
elements in non-subclasses (in root classes). - Customize parent classes with
hj:mapped-subclass
.
I've opted to the last solution and made MBObject
and ScheduleItem
mapped superclasses:
https://github.com/highsource/hyperjaxb3-support/blob/master/m/MindBody/src/main/wsdl/binding.xml#L60-L65
Thus classes like Appointment
become (in JPA sense) root of the hierarchy and the id customization works correctly (mapped supperclasses do not have ids). So I get a successful build (database tests fail but don't break the build).
来源:https://stackoverflow.com/questions/29125659/how-to-set-existing-id-as-primary-key-in-hyperjaxb3-cxf-project-code-generatio