Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.

Lazy Initialization Exceptions

Avatar

Level 2
Our Java naturally classes contain properties which are
relationships to other classes - either one to many or many to one.
Due to the fact that these relationships are so intertwined, many
given objects end up referencing a large portion of the database if
one were to recursively follow all of the nested relationships. As
such, we desire to have the option of not loading certain
relationships when the data is not needed.



We use EJB 3.0 (JBoss implementation using Hibernate) for
object persistence. It allows the option of uninitialized
collections and other referenced objects.



The Flex process of serialization to AMF causes serious
problems for this design. It tries to touch all of these properties
while building the binary representation for sending over the wire.
This triggers an immediate attempt to initialize the objects which
are still in the uninitialized state.



This causes the LazyInitializationException to be thrown by
the O/R framework - because the transaction is already closed
(which effectively means the call to the DAO has returned).



The community only offers two suggestions, both which do not
work with Flex (or Flash Remoting for that matter). T



he first is simply initializing everything ahead of time.
This does not work because eventually you have to draw the line
somewhere, and the Flex serialization routines will find that line
and try to cross it.



The second is the open session in view pattern, meaning that
we open the transaction as soon as the Flex client makes a request,
and close it only when the last response has been made. This does
not work either, because Flex would end up initializing everything
during serialization.



I have gone to the extent to writing a custom aspect to
intercept returning calls from my DAO and null out the Hibernate
proxies. This worked until I tried to use it for uninitialized many
to one relationships. Nulling them out actually deletes my
relationship in the database!



The only solution I see is to add intelligence to the Flex
serialization techniques which watch for this scenario, and avoid
triggering the lazy initialization.



Any suggestions would be appreciated.
3 Replies

Avatar

Level 2
We have the same problem with the hibernate assembler (not
surprising!).



Just after beta 3 went out, I changed the code so that if
your association properties are marked with "lazy=true" that we do
not do a deep traversal on the properties of that object for the
"createSequence" operation. Only the id of the referenced item is
accessed in this case. In other words, when your assembler has a
lazy association, you can return a hollow instance for any
properties which reference lazy associations. For single-valued
associations, this is great because hibernate makes the id of the
item available even if the properties have not yet been fetched.
For multi-valued associations, hibernate does not even fetch the
list of referenced items by default so we still need to "touch" the
collection while the transaction is open to make sure the ids of
the reference items are fetched.



In the hibernate assembler in beta3, we have a method which
fetches all of the properties of all objects - i.e. it pulls in the
entire reachable sub-graph of objects which is what the sequencing
code in beta 3 will also do before returning any object from the
assembler. In the version post-beta 3, the code only fetches the
state of non-lazy associations, and fetches just the first level of
objects for multi-valued associations.



So in beta3, you could just live with this deep traversal and
this restriction will be removed in the final release. Another
option is to turn off auto-sync-enabled since the deep traversal is
only required if you clients are receiving changes made.

Avatar

Level 2
I spent considerable time last year documenting this concept
for the people at Hibernate, in an attempt to show them clearly how
the library needs enhancement to accomodate this scenario, and
volunteered to develop the patch. They refused to accept the
changes at the highest levels of the team.



I think you realize we are not using the hibernate assembler,
but EJB3.0 through the java adapter, so the changes made to the
hibernate assembler would not effect our application...



The cat's meow would be for Flex to interrogate the
annotations of the Java class at runtime. This would require Java
1.5, but that's OK with us! When it finds either of these
annotations, it would not traverse the relationship:



@ManyToOne(fetch=FetchType.LAZY)

@OneToMany(fetch=FetchType.LAZY)



Please note that the default for @OneToMany is
FetchType.LAZY, so the annotation would really look like this:



@OneToMany



Annotations could be used to a great extent in the java side
of Flex, to recognize security domain, the type of relationships
present on a Class (as above), and especially the primary key. The
@Id annotation should be used in lieu of the info in an XML
configuration file.



For now, we have further modified our AOP aspect to make it
work for the many-to-one association, so we have now have a
solution developed to get around this problem. All associations now
come back null to the Flex java adapter unless initialized in
advance.

Avatar

Level 1

quote:




Originally posted by:
busitech


Our Java naturally classes contain properties which are
relationships to other classes - either one to many or many to one.
Due to the fact that these relationships are so intertwined, many
given objects end up referencing a large portion of the database if
one were to recursively follow all of the nested relationships. As
such, we desire to have the option of not loading certain
relationships when the data is not needed.



We use EJB 3.0 (JBoss implementation using Hibernate) for
object persistence. It allows the option of uninitialized
collections and other referenced objects.



The Flex process of serialization to AMF causes serious
problems for this design. It tries to touch all of these properties
while building the binary representation for sending over the wire.
This triggers an immediate attempt to initialize the objects which
are still in the uninitialized state.



This causes the LazyInitializationException to be thrown by
the O/R framework - because the transaction is already closed
(which effectively means the call to the DAO has returned).



The community only offers two suggestions, both which do not
work with Flex (or Flash Remoting for that matter). T



he first is simply initializing everything ahead of time.
This does not work because eventually you have to draw the line
somewhere, and the Flex serialization routines will find that line
and try to cross it.



The second is the open session in view pattern, meaning that
we open the transaction as soon as the Flex client makes a request,
and close it only when the last response has been made. This does
not work either, because Flex would end up initializing everything
during serialization.



I have gone to the extent to writing a custom aspect to
intercept returning calls from my DAO and null out the Hibernate
proxies. This worked until I tried to use it for uninitialized many
to one relationships. Nulling them out actually deletes my
relationship in the database!



The only solution I see is to add intelligence to the Flex
serialization techniques which watch for this scenario, and avoid
triggering the lazy initialization.



Any suggestions would be appreciated.