Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental Feature - Freeze and detach beans (and attach) #3317

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

rbygrave
Copy link
Member

@rbygrave rbygrave commented Jan 30, 2024

  • Frozen beans as ReadOnly + Unmodifiable collections

  • Add Transaction.freezeAndDetach() returning FrozenBeans

  • Add Transaction.attach( FrozenBeans )

  • InterceptReadOnly now supports lazy loading

  • Query.setReadOnly(true) now uses InterceptReadOnly [when it used to ALSO require Query.setDisableLazyLoading(true)}

  • Add EntityBeanIntercept.errorOnLazyLoad (such that lazy loading on frozen bean is an error)

  • BeanList, BeanSet, BeanMap are now freezable

  • ModifyAwareList Set and Map are now freezable

  • Adds FrozenBeans [marker] interface for the frozen and detached beans [which can then be attached to other transactions and used as cached/frozen beans to seed the persistence context]


Expected use case

For performance reasons as a "caching mechanism" where there is good value in using unmodifable beans with potentially a significant amount of relationships and related data that is all infrequently changing.

These beans that are cached and used will often be graphs of related objects and represent some relatively infrequently changing "meta data".

Building frozen beans - freezeAndDetach()

  private FrozenBeans buildFrozenBeans() {
     try (Transaction txn = DB.beginTransaction()) {

       List<Customer> list = DB.find(Customer.class)
         .setReadOnly(true)
         .orderBy("id")
         .setMaxRows(3)
         .findList();

       // perform some lazy loading if we desire
       for (Customer customer : list) {
         customer.getContacts().size();
         Address billingAddress = customer.getBillingAddress();
         if (billingAddress != null) {
           Country country = billingAddress.getCountry();
           if (country != null) {
             country.getName();
           }
         }
       }

       return txn.freezeAndDetach();
     }
   }

Using frozen beans - attach()

  FrozenBeans frozenBeans = ...;

  try (Transaction txn = DB.beginTransaction()) {

    txn.attach(frozenBeans);

    List<Order> orders = DB.find(Order.class)
        .findList();
   ...
}

- Frozen beans as ReadOnly + Unmodifiable collections
- Add Transaction.freezeAndDetach() returning FrozenBeans
- Add Transaction.attach( FrozenBeans )

- InterceptReadOnly now supports lazy loading
- Query.setReadOnly(true) now uses InterceptReadOnly [when it used to ALSO require Query.setDisableLazyLoading(true)}
- Add EntityBeanIntercept.errorOnLazyLoad (such that lazy loading on frozen bean is an error)

- BeanList, BeanSet, BeanMap are now freezable
- ModifyAwareList Set and Map are now freezable
@rbygrave rbygrave self-assigned this Jan 30, 2024
They are marked as unloaded which means accessing the collection will
throw a PersistenceException.

e.g. customer.getOrders() will throw PersistenceException rather than
return an empty list.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant