我面临以下问题。我们正在使用服务数据对象,因为我们的目标运行时是 IBM WebSphere,它应该是该 API 的本机。我们使用的堆栈是 Java EE、Eclipse Oxygen 作为主要 IDE、根据 SDO 2.1.0 规范的 SDO 参考实现、IBM WebSphere 9 和 JRE8。
根据 SDO javadoc,define(java.io.InputStream xsdInputStream, java.lang.String schemaLocation)在类下有一个方法XSDHelper可以将所需的 XSD 模式加载到 WAS 运行时中。一旦模式被加载,它的类型就可用于其他操作,包括DataObject创建。我定义模式的方式如下所示:
InputStream is = new BOStorage().getInputStreamXSD("/test.xsd");
XSDHelper.INSTANCE.define(is, null);
该define()方法从 EJB 构造函数调用。
test.xsd位于我的 Eclipse 项目的src文件夹下。
src
| test.xsd
| test1.xsd
|
|___ejb.package.name
现在稍微介绍一下 test.xsd 本身。它引用了另一个相同targetNamespaceusing<include>标签的 XSD:
test.xsd 片段:
...
<xsd:schema
targetNamespace="http://ejb/package/name"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:bons0="http://ejb/package/name">
<xsd:include schemaLocation="test1.xsd"></xsd:include>
<xsd:include schemaLocation="test2.xsd"></xsd:include>
<xsd:complexType name="TestSDO">
...
<xsd:element minOccurs="0" name="RefObject"
type="bons0:RefObject">
</xsd:element>
...
test1.xsd包含一个complexType命名RefObject的 ,在 中引用test.xsd。
test1.xsd 片段:
...
<xsd:complexType name="RefObject">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="type"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
...
正如 2.1.0 版的官方 SDO Java 规范所说:
9.7 XSD 映射细节
...
- 所有
<group>引用、<attributeGroup>引用、<include>s 和<import>s 都完全扩展为等效的 XSD,就好像这些声明不存在一样。...
对于我的愿景,这意味着在我的情况下,SDO 实施应该:
加载test.xsd;
弄清楚,它
test1.xsd在其<include>部分中引用了;由于
test1.xsd位于同一个src文件夹test.xsd中,我的期望是它会隐式加载到 WebSphere 运行时环境中。
但是我在尝试创建RefObject类型的 DataObject 时遇到错误:
CWSDO0001E: 无法创建类型为 { http://ejb/package/name }RefObject 的数据对象,因为找不到该类型
我可以得出的结论是,SDO API 并非旨在以这种方式工作,或者我的 XSD 或任何 XSD 不适合或包含一些错误。
任何帮助将不胜感激。
更新: 在使用“全局”XSD(包括所有内联引用)的情况下,它的工作方式与预期一样。我之前提到的一切都是从无状态 EJB bean 运行的。
导致错误的示例代码:
@Stateless(mappedName = "TestSDO")
@Remote(TestSDORemote.class)
@Local(TestSDOLocal.class)
public class TestSDO implements TestSDORemote, TestSDOLocal{
...
// default EJB constructor
public TestSDO() {
String textInfo = "";
try {
defineSDOTypes();
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Could not define SDO types");
}
}
...
private void defineSDOTypes() {
HelperContext hc =
SDO.getHelperContextFactory().createHelperContext("ScopeManagerTestID",
null);
XSDHelper xsdHelper = hc.getXSDHelper();
try (InputStream is = new BOStorage().getInputStreamXSD("/test.xsd")) {
xsdHelper.define(is, null);
} catch (IOException e) {
LOGGER.logp(Level.WARNING, CLASS_NAME, METHOD_NAME, "Unable to load the
schema: " +
"test.xsd" + ": " + e.getMessage());
e.printStackTrace();
}
...
// creates the target Data Object (here comes the error)
private void createBO(){
DataObject dob = DataFactory.INSTANCE.create("http://ejb/package/name",
"RefObject");
}
...