Ticket #289 (closed enhancement: fixed)

Opened 4 years ago

Last modified 4 years ago

Allow client code to participate in role creation during lifting

Reported by: stephan Owned by:
Priority: major Milestone: OTDT_1.3.1
Component: runtime-environment Version: 1.3.0
Keywords: Cc:

Description

This occurred when implementing lazy loading for EclipseLink:

When a team is retrieved from persistent storage lazy loading recommends that its roles are not loaded at that point in time. When subsequently a base object is lifted for that team, lifting must be capable of retrieving an existing role instead of creating a fresh one.

Since the logic for retrieving roles is not a responsibility of OT/J, it should be possible to hook client code into the lifting logic, that can feed roles into the infrastructure.

Change History

Changed 4 years ago by stephan

Commits r21960, r21961, r21962, r21966 implement the following:

The OTRE now checks for a property ot.lifting.participant. If set this is interpreted as a fully qualified name of a class that must implement the following method:

public static Object createRole(Team teamInstance, Object base, String roleClassName) {...}

This method is invoked, whenever lifting fails to retrieve the desired role from the team's internal role cache.

If createRole returns a non-null value, this value is considered by the runtime as being the desired role (i.e., it must be castable to that role type), and no new role is created. If createRole returns null, lifting proceeds as normal, i.e., creates a fresh role using the default lifting constructor.

An initial test is given in 2.2.36-otjld-lifting-participant-1 which demonstrates how a lifting participant can use reflection to redirect role creation to a different constructor than the default lifting constructor (here: adding an int parameter by which all lifted roles are numbered).

While it was an important design choice to introduce the indirection of a lifting participant only when needed, invoking the lifting participant for all roles even when only a few should be affected will still incurr undesirable impact on performance. Thus, we might want to support inclusion/exclusion filters:

  • ot.lifting.participant.include=classpattern
    delegate to the lifting participant only for classes matching the given pattern.
  • ot.lifting.participant.exclude=classpattern
    do not delegate to the lifting participant for classes matching the given pattern.

Leaving this ticket open, to wait and see if this implementation actually satisfies the needs by the EclipseLink integration.

Changed 4 years ago by stephan

When deploying a lifting participant, care must be taken, that all teams can access that participant's class.

In an OT/Equinox setting this might be a little tricky, which gives even more motivation to restricting delegation to certain team classes.

Thinking more of OT/Equinox actually suggests, that

  • a lifting participant be installed using an extension point
  • a lifting participant be an instance rather than a class, which btw also solves the visibility issue.

To facilitate delegation to a lifting participant instance, the following should be considered:

  • introduce an interface org.objectteams.ILiftingParticipant
  • when configuring a lifting participant, the runtime should instantiate the given class, create a static field (of type ILiftingParticipant) in org.objectteams.Team, and use this field for delegation.

Here, "configuring a lifting participant" applies to both the property based approach as well as the one using an extension point.

A field in Team is used rather than each individual team class, because the runtime would otherwise have difficulties assigning the lifting participant instance to a class being transformed.

Changed 4 years ago by stephan

This change from comment:2 is implemented in r21974:

  • use interface org.objectteams.ILiftingParticipant
  • when configuring a lifting participant, the runtime should instantiate the given class, create a static field (of type ILiftingParticipant) in org.objectteams.Team, and use this field for delegation.

The static field is Team._OT$liftingParticipant.

Changed 4 years ago by stephan

  • status changed from new to closed
  • resolution set to fixed

Tests regarding JPA lazy loading using a lifting participant pass.

Exposing this mechanism to OT/Equinox is subject of #290.

Note: See TracTickets for help on using tickets.