We converted a field of a BusinessData object from long to String. Now we face index recreation problems after upgrading the ivy engine to a new version.

2019-05-06 15:36:36.038 ERROR [ch.ivyteam.ivy.business.data.store.search.internal.BusinessDataSearchIndecesRecreator] [ivy immediate job pool-thread-1] [executionContext=SYSTEM] 
  Recreation of business data search index failed
    [errorId=16A8D5C46C63FD9B, executionContext=SYSTEM]
    ch.ivyteam.ivy.business.data.store.search.internal.elasticsearch.ElasticsearchException: Elasticsearch add documents to index failed because of: One or more of the items in the Bulk request failed, check BulkResult.getItems() for more information.
    bulk error: id=f08fe3d90a454be4b95a0b59785686ff, index=ivy.businessdata-com.axonivy.hrwf.vea.arbeitsvertragsaenderungencasemodel, error={"type":"illegal_argument_exception","reason":"mapper [antrag.lohnUndOderArbeitszeitaenderung.baseSalaryPtNew] cannot be changed from type [float] to [long]"}
    bulk error: id=b15b99eb022b4e1f95cd1b34ee03ae2f, index=ivy.businessdata-com.axonivy.hrwf.vea.arbeitsvertragsaenderungencasemodel, error={"type":"mapper_parsing_exception","reason":"failed to parse [antrag.lohnUndOderArbeitszeitaenderung.expensesPtCurrent]","caused_by":{"type":"number_format_exception","reason":"For input string: \"CHF500\""}}

How can we get a proper data store and make the index recreation running?

asked 07.05.2019 at 04:23

SupportIvyTeam's gravatar image

SupportIvyTeam ♦♦
accept rate: 77%

The error occurs as ElasticSearch determines the type of a field once the first non empty value is defined. So if a BusinessData object with long expensesPtCurrent is once persistent, the type can be changed to String without facing compatiblity issues.

To takle the problem I'd write a conversion in Java to:

  1. read old values (where the field was a long) as raw JSON
  2. load and update the persistent businssData object and apply a compatible value in new format (String)
  3. store the updated value in BusinessData repo


public static void convertLegacy() throws IOException
      ObjectMapper mapper = new ObjectMapper();
      BusinessDataRepository repository = BusinessDataRepository.get();
      List<BusinessDataInfo<Antrag>> infos = repository.search(Antrag.class).execute().getAllInfos();
      for(BusinessDataInfo<Antrag> info : infos)
          String json = BusinessDataSearchIndex.toSearchIndexJson(info.getRawValue());
          JsonNode node = mapper.readTree(json); // JSON = simple API to work with JSON objects
          JsonNode ptCurr = node.get("lohnUndOderArbeitszeitaenderung").get("expensesPtCurrent");
          if (ptCurr.isLong())
              // legacy value
              long oldVal = ptCurr.asLong();
              Antrag antrag = repository.find(info.getId(), Antrag.class);
              antrag.setExpensesCurrent(String.valueOf(oldVal)+ " CHF");

To avoid the problem at all:

Do not change the type of already persistent data. But add a new replacement field. Optionally with fallback support to read legacy values. See: https://answers.axonivy.com/questions/2606/can-not-persist-business-data-to-repo-after-changing-data-type


answered 07.05.2019 at 04:28

Reguel%20Wermelinger's gravatar image

Reguel Werme... ♦♦
accept rate: 70%

edited 07.05.2019 at 04:30

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here



Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "Title")
  • image?![alt text](/path/img.jpg "Title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported



Asked: 07.05.2019 at 04:23

Seen: 4,258 times

Last updated: 07.05.2019 at 04:30