In our application, we store sometimes ids of corrsponding business data to the process data of the current running task. This allows us to load the business data fresh from the repository after a task-switch, by the stored id.

Question 1: Is a Business Data linked to the ClassLoader of PMV task/case belongs to?

Question 1: When we load a Business Data from a Repository directly, in another PMV (then the Business Data was created), how is the handling? Do this leads to deserialization problems, as it happen with process data, because of conflicting Classloaders?

asked 10.01.2017 at 11:17

SupportIvyTeam's gravatar image

SupportIvyTeam ♦♦
1.4k102118122
accept rate: 77%


If the Business Data API use internally a type for deserialization, the type must be passed to the API.

For example, find and search requires a type:

ivy.repo.find("myId", foo.bar.Customer.class);
ivy.repo.search(foo.bar.Customer.class)

Basically, all further type information is determined by this type. This should work for most cases, without class loading conflicts, since a Business Data entry is not related to a specific PMV, as we know from the process data.

Internally, no information about the type is serialized to a field when the type of the values of the fields matches the defined type of the field. So all needed type information can be determined by the given type.

Example:

The class Customer has the following fields defined:

  • name: String
  • age: Number
  • address: Address

The Business Data is stored and loaded by the following script:

in.customer.name = “Chuck Norris”;
in.customer.age = 25;
// type of field customer is Address, so ..
in.customer = new Address(); // .. the value matches the type of the field
in.customer.address.street = “Baarerstrasse 123”

// store the customer and get the id
Number id = ivy.repo.getId(ivy.repo.save(in.customer));

// load the customer again by it's id
ivy.repo.find(in, foo.bar.Customer.class);

If we only have one project and all used classes are defined in the same project, the above example will work successfully, till the end of the world..

Extended Use Cases:

What happen, when a class has new or removed fields (compared to the class, the Business Data entry was stored)?
That's simple. When loading a business data entry they are ignored, when the business data gets saved only known fields are stored. This could lead to data loss. E.g. when two PMVs have not the same version of a data class and both save the same business data, they will overwrite each other’s data.

What happen, when an instance of a field has not the same type as the field is defined in the class?

Example:

We extend the class Address

Public class MyCustomAddress extends Address {…}

And use them in our example script:

In.customer.name = “Chuck Norris”;
In.customer.age = 25;
In.customer = new MyCustomAddress(); // instance is NOT of same type as the field address
In.customer.address.street = “Baarerstrasse 123”
Number id = Ivy.repo.getId(Ivy.repo.save(in.customer));
Ivy.repo.find(in, foo.bar.Customer.class);

The Business Data API tries to handle it. The serializer will store the fullname of the class as String to the serialized-data. On deserialization, the class gets resolved by its fullname. For this, the class loader of the current executing Task is used. This allows, that the class MyCustomAddress can be defined in a higher project than the Customer class.

All this is handled internally by the Jackson deserializer. We just set the class loader of the case project as context class loader on the thread, before calling the Jackson deserialization.

Currently there is no API to set a Classloader as Context Class Loader, since it wasn’t used yet.

However, this means too, that a project (like a Portal) which shows a list of Business Data of other projects, has to be the most upper project in the dependency hierarchie, so that the Business Process API is able to find used types – or they are at least in a shared library. The use of interfaces, inheritance should be limited to special cases, so that problems do not occur at all. Instead, try to use composition whenever possible…

link

answered 10.01.2017 at 17:00

Flavio%20Sadeghi's gravatar image

Flavio Sadeghi ♦♦
(suspended)
accept rate: 75%

hi. For the case instance of a field has not the same type as the field is defined in the class, if in PMV1 i store data with type Address, then next version i get out with type MyCustomerAddress, it's still possible, right?

(12.01.2017 at 10:24) trungdv trungdv's gravatar image

Yes - if the field address in PMV X is of type Address and in PMV Y of type MyCustomerAddress - load and save works, since no type information is serialized. But as described, only known fields are saved, because the field definition and the instance has the same type. Not existing fields in one version of Address/MyCustomerAddress will be deleted, after a save...

(13.01.2017 at 09:48) Flavio Sadeghi ♦♦ Flavio%20Sadeghi's gravatar image
Your answer
toggle preview

Follow this question

By Email:

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

By RSS:

Answers

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

Tags:

×17

Asked: 10.01.2017 at 11:17

Seen: 2,446 times

Last updated: 19.01.2017 at 09:22