How should we annotate Java entities to persist lists and then make lazy loading work?

In Java, I have a requirement to allow user-defined properties.

Example:
Database table: property

Table Row:
ID: 1
Label: Annual Salary

Database table: contact
ID: 1
Email: test@example.com
...

In addition to existing columns for contacts, users will define their own columns in Property Manager. Such column is "Annual Revenue" (number) for example.

So we need a table:
Database table: contact_properties
ID: 1
Contact_id: 1
Property_id 1

In this table we link user-defined properties to contacts

We however need more. We have 4 fixed (immutable) field types: Text, Number, Checkbox, Dropdown.
Every user-defined property should have a type, something like in MS Excel, but easier.

And finally, every user-defined property should belong to some group. Groups are user-defined too.

Database table: property_group

Row:
ID: 1
Label: Contact Information

ID: 2
Label: Company information

...

How should we annotate entities in Java to persist the above? Attached is all source code (mini project). See the entity package in module-properties. I have also prepared something quickly in the App.java (main) to test persistence.

The current exceptoin is:
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: uk.co.mybigdata.crm.module.properties.entity.Property.optionList, could not initialize proxy - no Session
      at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:582) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
      at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:201) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
      at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:561) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
      at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:132) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
      at org.hibernate.collection.internal.PersistentBag.toArray(PersistentBag.java:283) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
      at uk.co.mybigdata.crm.application.App.run(App.java:85) [classes/:na]
      at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:797) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
      ... 5 common frames omitted
elements.zip
LVL 1
Jack McKenzieChief Executive Officer http://mybigdata.co.ukAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

girionisCommented:
It seems that you're trying to access the entities after the session is closed.

Can you try to process everything within a transaction?

org.hibernate.Transaction tx = session.beginTransaction(); 
...
tx.commit();

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Jack McKenzieChief Executive Officer http://mybigdata.co.ukAuthor Commented:
Transactions are managed by the container, as you see in the code, so I have annotated App.java run() with @Transactional and it has helped!

The full answer comes from StackOverflow (the exact same stack trace - Hibernate attempts to lazy load from a bag, uses a temporary session if needed, then throws the exception because the session has been closed = same last 3 stack trace steps).

https://stackoverflow.com/questions/19304671/cannot-fetch-lazy-jpa

The solution is to eager load the collection, or annotate the method @Transactional, or make the session scope broader, possibly with a filter.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.