Thanks for taking the time to document this, Oscar... I've added a note to our website for this recommendation here [1]
Dan [1] http://isis.apache.org/components/objectstores/jdo/managed-1-to-m-relationships.html ~~~~~~~~~~~~~ On 1 May 2014 09:21, GESCONSULTOR - Óscar Bou <o....@gesconsultor.com>wrote: > > Just for others with the same problem. > > Seems there's a bug somewhere in DN, but there's an easy workaround. > > > The situation generating the NPE was the following: > > Domain Entity: > > @PersistenceCapable > @Inheritance(strategy = InheritanceStrategy.NEW_TABLE) > public class InformationSystem extends ApplicationComponent { > > > // {{ ParentSystem (property) > private InformationSystem parentSystem; > > @MemberOrder(sequence = "100") > @Column(allowsNull = "true") > public InformationSystem getParentSystem() { > return this.parentSystem; > } > > public void setParentSystem(final InformationSystem > partOfInformationSystem) { > this.parentSystem = partOfInformationSystem; > } > > // }} > > // {{ SubSystems (Collection) > @Persistent(mappedBy = "parentSystem", dependentElement = "false") > private SortedSet<InformationSystem> subSystems = new > TreeSet<InformationSystem>(); > > @MemberOrder(sequence = "500") > public SortedSet<InformationSystem> getSubSystems() { > return this.subSystems; > } > > public void setSubSystems(final SortedSet<InformationSystem> > subSystems) { > this.subSystems = subSystems; > } > > // }} > > ... > > } > > Obviously, the exception is thrown because we are using managed > relationships, so DN tries to keep synched both sides. > > That's relevant, because in this case we were trying to set the > relationship as this: > > subSystem.setParentSystem(informationSystem); > > When executed, the previous line was causing the NPE on DataNucleus. > > If, instead, we update the bidir relationship with: > > informationSystem.getSubSystems().add(subSystem); > > > It runs smoothly. > > As it was inside a Fixture, and we weren't wrapping the call, as in (an > "idiom" we have adopted in all our domain code, unless properties/actions > are hidden or disabled): > > wrapperFactory.wrap(subSystem).setParentSystem(informationSystem); > > The exception was thrown when persisting another entity, which in our > case, also executes a this.getContainer().flush(), as any action executed > inside a wrap(..). > > > So, summarizing, when having a bidirectional 1-n relationship that must be > automatically managed by DataNucleus, it's preferred to "add" to the > parent's child collection, than set the parent on the child. > > > HTH, > > Oscar > > > > > > El 29/04/2014, a las 23:13, Dan Haywood <d...@haywood-associates.co.uk> > escribió: > > > On 29 April 2014 21:34, GESCONSULTOR - Óscar Bou <o....@gesconsultor.com > >wrote: > > > Yes... relMgr is what I find to be null... > > I noticed it sometimes worked, sometimes not... I thought about a limit in > nested transactions or something similar... But I didn't noticed it was a > ConcurrentMap. > > The only option seems the one you pointed. The Map has been cleared and > not initialized on: > > if (getManageRelations() && managedRelationDetails != null) > { > managedRelationDetails.clear(); > } > > > > I think it's probably worth asking on the DN forum (Andy Jefferson). Say > you work with me. He'll probably ask for a test case, but I guess you > could explain that's intermittent and possibly a threading issue. > > Also, do note that we're not on the latest version of DN; very outside > change that it's a bug that's been recently fixed. > > > > > > While trying as a workaround to "hide" the exception in a try - catch > block, as in: > > > // Send pending changes to the database. > try { > this.getContainer().flush(); > } catch (final NullPointerException e) { > // Do nothing... Seems there's a bug in DN when updating > Managed > // Relationships. > // It only occurs sometimes (it's lacy loaded; it's a > multi-threaded > // ConcurrentMap. > System.err.print(String.format("XMS - FLUSING ERROR !!!: %s", > e.getStackTrace().toString())); > } > > > > Then the Isis transaction was not in the correct state: > > Caused by: java.lang.IllegalStateException: state is: MUST_ABORT > at > org.apache.isis.core.commons.ensure.Ensure.ensureThatState(Ensure.java:111) > at > > org.apache.isis.core.runtime.system.transaction.IsisTransaction.flush(IsisTransaction.java:363) > > at > > org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.flushTransaction(IsisTransactionManager.java:311) > at > > org.apache.isis.core.runtime.persistence.internal.RuntimeContextFromSession$7.flush(RuntimeContextFromSession.java:223) > at > > org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault.flush(DomainObjectContainerDefault.java:229) > > Not sure how to deal with it ... > > > > > Not sure I recommend this, but if you want to hack it, you could register a > custom implementation of DomainObjectContainer that resets the > IsisTransaction back to a good state (setState to IN_PROGRESS and > setAbortCause to null. > > in isis.properties: > > > isis.persistor.domain-object-container=org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault > > change as required... > > As I say, rather hacky, not sure it's to be recommended. > > Dan > > > > Óscar Bou Bou > Responsable de Producto > Auditor Jefe de Certificación ISO 27001 en BSI > CISA, CRISC, APMG ISO 20000, ITIL-F > > 902 900 231 / 620 267 520 > http://www.twitter.com/oscarbou > > http://es.linkedin.com/in/oscarbou > > http://www.GesConsultor.com <http://www.gesconsultor.com/> > > > > Este mensaje y los ficheros anexos son confidenciales. Los mismos > contienen información reservada que no puede ser difundida. Si usted ha > recibido este correo por error, tenga la amabilidad de eliminarlo de su > sistema y avisar al remitente mediante reenvío a su dirección electrónica; > no deberá copiar el mensaje ni divulgar su contenido a ninguna persona. > Su dirección de correo electrónico junto a sus datos personales constan en > un fichero titularidad de Gesdatos Software, S.L. cuya finalidad es la de > mantener el contacto con Ud. Si quiere saber de qué información disponemos > de Ud., modificarla, y en su caso, cancelarla, puede hacerlo enviando un > escrito al efecto, acompañado de una fotocopia de su D.N.I. a la siguiente > dirección: Gesdatos Software, S.L. , Paseo de la Castellana, 153 bajo - > 28046 (Madrid), y Avda. Cortes Valencianas num. 50, 1ºC - 46015 (Valencia). > Asimismo, es su responsabilidad comprobar que este mensaje o sus archivos > adjuntos no contengan virus informáticos, y en caso que los tuvieran > eliminarlos. > > > > > >