ISIS:Blob / Clob字段序列化问题

时间:2019-03-28 14:49:40

标签: java jdo datanucleus isis

编辑:解决方案: 升级到ISIS 1.17.0并设置属性isis.persistor.datanucleus.standaloneCollection.bulkLoad=false解决了前两个问题。


我正在使用Apache ISIS 1.16.2,并且尝试将Blob / Clob内容存储在 MariaDB 数据库(v10.1.35)中。因此,我使用数据库连接器org.mariadb.jdbc.mariadb-java-client(v2.3.0),并在代码中使用@Persistent批注,如许多示例和ISIS文档所示。

使用下面的代码,我只得到一个名为content_name的单列(其中Blob对象以二进制形式序列化),而不是三列content_namecontent_mimetype和{ {1}}。

这是 Document 类,其Blob字段为content_bytes

content

这将为DomainObject类@PersistenceCapable(identityType = IdentityType.DATASTORE) @DatastoreIdentity(strategy = IdGeneratorStrategy.IDENTITY, column = "id") @DomainObject(editing = Editing.DISABLED, autoCompleteRepository = DocumentRepository.class, objectType = "Document") @Getter // ... public class Document implements Comparable<Document> { @Persistent( defaultFetchGroup = "false", columns = { @Column(name = "content_name"), @Column(name = "content_mimetype"), @Column(name = "content_bytes", jdbcType = "BLOB", sqlType = "LONGVARBINARY") }) @Nonnull @Column(allowsNull = "false") @Property(optionality = Optionality.MANDATORY) private Blob content; // ... @Column(allowsNull = "false") @Property private Date created = new Date(); public Date defaultCreated() { return new Date(); } @Column(allowsNull = "true") @Property @Setter private String owner; // ... } 创建以下模式,而Blob字段只有一列:

Document

通常,ISIS框架的类CREATE TABLE `document` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `content_name` mediumblob, `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `owner` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 应该进行映射。但是似乎该Mapper某种程度上没有参与...

1。问题:如何将Blob字段分为三列(如上所述和许多演示项目中所述)。即使我切换到HSQLDB,我仍然只会得到一列,因此MariaDB可能不会有问题。

2。问::如果我在从另一个DomainObject类继承的类中使用Blob / Clob字段,则通常会得到一个org.apache.isis.objectstore.jdo.datanucleus.valuetypes.IsisBlobMapping(见下面的堆栈跟踪),而不能做它的开头或结尾。处理继承有哪些潜在的陷阱?为什么会出现此异常?

3。问题:我需要存储属于域对象的文档(您可能已经猜到过)。这样做的正确方法是将文档存储在文件系统树中,而不是数据库中(默认情况下,对象数据库还有一些大小限制),然后在对象中引用文件。在Datanucleus documentation中,我发现扩展org.datanucleus.exceptions.NucleusException应该可以做到这一点。我通过在Blob字段中添加行serializeToFileLocation来进行尝试,但是没有任何反应。所以我的问题是:这个Datanucleus扩展与Apache Isis兼容吗?

如果该扩展名与Isis冲突,是否有可能将@Extension(vendorName="datanucleus", key="serializeToFileLocation" value="document-repository")javax.jdo.listener.StoreLifecycleListener将Blob存储在文件系统上,然后再将域对象持久保存到数据库中并在加载之前将其还原?有更好的解决方案吗?

仅此而已。先感谢您! ;-)


堆栈跟踪到问题2:

org.apache.isis.applib.AbstractSubscriber

1 个答案:

答案 0 :(得分:1)

经过研究,我认为问题问题1 和2 的问题似乎与this ISIS bug report #1902有关。

简而言之:数据核扩展插件解析机制似乎找不到ISIS值类型适配器,因此无法知道如何序列化ISIS的Blob / Clob类型。

根据上述ISIS错误报告,此问题已在1.17.0中修复,因此我正尝试从1.16.2升级到此版本(引入了许多其他问题,但这将是一个额外的主题)。 / p>

对于问题3 ,我发现Minio基本上解决了我的问题,但是对于我的需求来说,它有点过大。我将继续寻找将Blob / Clob存储到本地文件系统的其他解决方案,并会牢记Minio ...

更新

  1. 我将项目升级到ISIS版本1.17.0。它解决了问题1中的问题(现在我为Blob / Clob对象得到了三列)。
  2. 升级无法解决问题2(NucleusException)中的问题。我发现只有在返回带有Blob / Clob字段的DomainObjects列表时(即呈现为独立表的情况),才会抛出该错误。如果直接进入对象的实体视图,则不会引发任何异常,并且可以查看/修改/下载Blob / Clob内容。
  3. 与此同时,我编写了自己的datanucleus插件,该插件将Blob / Clob作为文件存储在文件系统上。

更新2

  1. 我找到了一种解决org.datanucleus.exceptions.NucleusException: Unable to create SQLExpression for mapping of type "org.apache.isis.objectstore.jdo.datanucleus.valuetypes.IsisClobMapping" since not supported解决方案。批量加载似乎是一个问题(但我不知道任何详细信息)。 通过属性isis.persistor.datanucleus.standaloneCollection.bulkLoad=false(最初由ISIS原型设置为true)停用批量加载解决了这个问题。