我面临以下问题。我们正在使用服务数据对象,因为我们的目标运行时是 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 本身。它引用了另一个相同targetNamespace
using<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");
}
...