問題
- ある環境(例:dev)から他の環境(例:uat)にオブジェクト定義を更新しようとすると、以下のエラーで処理が失敗します:
com.liferay.object.exception.ObjectFieldNameException$MustNotBeDuplicate: Duplicate name objectFieldName
at com.liferay.object.service.impl.ObjectFieldLocalServiceImpl._validateName(ObjectFieldLocalServiceImpl.java:1407) ~[?:?]
at com.liferay.object.service.impl.ObjectFieldLocalServiceImpl._addObjectField(ObjectFieldLocalServiceImpl.java:813) ~[?:?]
at com.liferay.object.service.impl.ObjectFieldLocalServiceImpl.addCustomObjectField(ObjectFieldLocalServiceImpl.java:136) ~[?:?]
環境
- Liferay DXP 7.4
解像度
- ソース環境とターゲット環境で同じ名前を持つフィールドが、同じ externalReferenceCode を持つことを確認してください。
- DXP 7.4 2024.Q1では、オブジェクト定義GUIからオブジェクト・フィールドのexternalReferenceCodeを参照または更新することができません。 ObjectDefinition APIを使用する必要があります。
使用するAPI:
- 両方の環境でこの API を使用して、objectDefinitionId(xxxxx) を使用してオブジェクト定義の各フィールドのobjectFieldId を取得します:
GET /o/object-admin/v1.0/object-definitions/xxxxx
- objectFieldId(yyyyy) を指定してオブジェクト・フィールドのexternalReferenceCode を読み取るには、両方の環境でこの API を使用します:
GET /o/object-admin/v1.0/object-fields/yyyyy
- そして最終的には、ソース環境でこのAPIを使用して、objectFieldId(yyyyy)を指定されたオブジェクト・フィールドのexternalReferenceCodeがターゲットと一致するようにパッチを当てる:
PATCH /o/object-admin/v1.0/object-fields/yyyyy
を次のようなボディで書いた:
{
"externalReferenceCode": "70c0d71c-ba78-f4df-61b8-4db5e4ba8aeb"
}
同じ名前のオブジェクト・フィールドが両方の環境で一致する外部参照コードを持つようになれば、すぐに再試行できます。
追加情報
- オブジェクト定義が更新されると、Liferayはオブジェクトフィールドのリストを調べ、それぞれについてフィールドを更新するか作成するかを決定します。
- LiferayはまずobjectFieldIdでフィールドをマッチさせようとします。
- そして、そのフィールドの外部参照コード(externalReferenceCode)で一致させようとする。
- 一致するフィールドがない場合、Liferayはフィールドを作成する必要があるとみなしますが、その作成はフィールド名の単一性ルールに違反します。
- このロジックは次の方法で見ることができる: https://github.com/liferay/liferay-portal/blob/master/modules/apps/object/object-service/src/main/java/com/liferay/object/service/impl/ObjectFieldLocalServiceImpl.java#L153
ほとんどの場合、この問題は起こるはずがない。 しかし、この問題が発生する典型的なシナリオを紹介しよう:
- オブジェクト定義はdevで作成され、エクスポートされ、uatでインポートされる。 この時点で、すべてのフィールドは両方の環境で同じ externalReferenceCode を持つ。
- 新しいフィールドが両方の環境に手動で追加された場合、両者は異なるランダムな外部参照コードを持つことになります。
- 次にdevからuatにオブジェクト定義をインポートする場合、APIを使用して同じexternalReferenceCodeを共有するように更新しない限り、手動で追加したフィールドのために更新が失敗します。