legacy-knowledge-base
公開されました Sep. 10, 2025

エンティティにBLOBフィールドがある場合、サービスビルダーを使用するとエラーが発生する。

written-by

Sergio Alonso

How To articles are not official guidelines or officially supported documentation. They are community-contributed content and may not always reflect the latest updates to Liferay DXP. We welcome your feedback to improve How To articles!

While we make every effort to ensure this Knowledge Base is accurate, it may not always reflect the most recent updates or official guidelines.We appreciate your understanding and encourage you to reach out with any feedback or concerns.

legacy-article

learn-legacy-article-disclaimer-text

問題

  • サービスビルダーについて、以下のサンプルエンティティを定義します。
<entity name="Documentos" remote-service="false" local-service="true" uuid="false" table ="REAJ_GESTION_DOCUMENTO" data-source="extDataSource">
<column name="id" type="long" db-name="ID" primary="true" id-type="sequence" id-param="REAJ_GESTION_DOCUMENTO_SEQ"/>
<column name="nombre" type="String" db-name="NOMBRE"/>
<column name="contenido" type="Blob" db-name="CONTENIDO"/>
<column name="fechaAlta" type="Date" db-name="FECHA_ALTA"/>
</entity>
  • エンティティに新しいレコードを挿入しようとすると、以下の例外が発生します:
Caused by: java.lang.NullPointerException        at org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValue(AbstractEntityTuplizer.java:521)
at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValue(AbstractEntityPersister.java:3868)
at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:100)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:450)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:282)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:143)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:713)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:701)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:697)
at com.liferay.portal.dao.orm.hibernate.SessionImpl.save(SessionImpl.java:252)
... 188 more

Environment

  • Liferay DXP with Liferay patched Hibernate library v3.6.10

解決策

  • BLOB フィールドを持つエンティティに新しいレコードを挿入する正しい手順は、2つのステップで行っています:
    • 最初のステップです: BLOB 型と異なるフィールドを追加する。
    • 第二段階です: BLOB フィールドを持つレコードを 更新する。
  • 前回のエンティティの例に対するスニペットです:
documento.setNombre(nombre);  
documento.setFechaAlta(new Date());
documento = documentosLocalService.addDocumentos(documento);

documento.setContenido(contenido);
documentosLocalService.updateDocumentos(documento);
  • 根本的な原因は Service Builder フレームワークが BLOB フィールドと残りのフィールドのセットの間に人工的な 1:1 関係を定義していることで、 Liferay パッチ付き Hibernate library v3.6.10を使用する場合です。
    • この場合、 BLOB フィールドはデフォルトの設定を使用していることに注意してください。 lazy="true".
  • この関係から、Hibernateは BLOB フィールドを最初に挿入し、その後、残りのフィールドのセットを挿入します。
  • BLOB フィールドを挿入するためには、主キーが必要である。 しかし、このプライマリーキーは、残りのフィールドの挿入が処理されたときにのみ生成されます。
  • つまり、 BLOB フィールドは、挿入操作のために参照される主キーを持っていないため、例外がスローされるのです。

did-this-article-resolve-your-issue

legacy-knowledge-base