Wanted to get some opinions. I am working on HHH-10055 which is basically a report of problems with that "lazy loading outside of a session/transaction" feature when used in combination with bytecode enhancement. The initial problem was that bytecode interception was not accounting for collection attributes properly; it was not building the appropriate PersistentCollection to return. I changed that code to now build the PersistentCollection.
But that led to another issue later on that made me question how I was building the PersistentCollection during interception. Essentially I was trying to still build an uninitialized PersistentCollection. The interception code immediately tries to read the size of that collection as and up-front part of its in-line dirty checking capabilities which triggered another interception back in to an inconsistent state. But what I started thinking about is the assumption that this interception ought to prefer to return an uninitialized PersistentCollection. I now think that is not a good assumption. Why? Consider code like: Well the idea of an uninitialized PersistentCollection comes from the scenario of proxy-based laziness. In proxy-based laziness, code like: MyEntity myEntity = session.load( MyEntity.class, 1 ); System.out.println( myEntity.getName() ); In the case of proxy-based laziness, the second line immediately causes the entire proxy to become initialized. Part of that is to set any of its collection attributes. However, as the collections are not accessed here we want to further delay initializing them. But since the proxy is initialized completely that means the only way to achieve that here is setting an uninitialized version of the PersistentCollection as state, which will initialize itself later when accessed. For bytecode enhancement, the situation is a little bit different. There we'd not even build the PersistentCollection instance until that attribute is accessed. So in the above code the collection attributes would never be built. So when we are in the interception code I mentioned above, we know that something is trying to access that collection attribute specifically. This is the difference. Back to the initial problem... I think the solution is not just to have the bytecode interception code build the PersistentCollection, but to also have it make sure that the PersistentCollection is initialized. Going back to the sample code, and adding a line: MyEntity myEntity = session.load( MyEntity.class, 1 ); print( myEntity.getName() ); myEntity.getChildren(); In the proxy-based solution the collection is still uninitialized after this. For bytecode interception I am proposing that the collection would be initialized by that 3rd line. Again we could return the uninitialized collection here, and wait for PersistentCollection to initialize itself on first "further access" (calling size(), iterating, etc). I am more think through intent; because we know specifically that the collection attribute itself was accessed it seems reasonable to go ahead and initialize it. And if we do not go that route, then we need a different tact as well for dealing with the in-line dirty checking aspect of this. Really the only time this distinction becomes an issue is in code that explicitly tries to check whether certain attributes are initialized. So whereas this works for the proxy-based approach: MyEntity myEntity = session.load( MyEntity.class, 1 ); if ( !Hibernate.isInitialized( myEntity.getChildren() ) ) { // do something with the uninitialized collection ... } It will fail with the bytecode interception approach I propose, because the call to `myEntity.getChildren()` itself causes the initialization. There you'd have to use: MyEntity myEntity = session.load( MyEntity.class, 1 ); if ( !Hibernate.isPropertyInitialized( myEntity, "children" ) ) { // do something with the uninitialized collection ... } which has always been the suggested way to deal with questioning bytecode initialization state and which matches the JPA call too. So any thoughts? _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev