atom feed6 messages in org.apache.incubator.isis-usersRe: java.lang.NullPointerException at...
FromSent OnAttachments
GESCONSULTOR - Óscar BouApr 29, 2014 12:49 pm 
Dan HaywoodApr 29, 2014 1:04 pm 
GESCONSULTOR - Óscar BouApr 29, 2014 1:34 pm.gif, .tiff, .gif, 2 more
Dan HaywoodApr 29, 2014 2:13 pm 
GESCONSULTOR - Óscar BouMay 1, 2014 1:21 am.gif, .tiff, .gif, 2 more
Dan HaywoodMay 1, 2014 4:10 am 
Subject:Re: java.lang.NullPointerException at org.datanucleus.ExecutionContextImpl.performManagedRelationships(ExecutionContextImpl.java:4003)
From:GESCONSULTOR - Óscar Bou (o.b@gesconsultor.com)
Date:May 1, 2014 1:21:28 am
List:org.apache.incubator.isis-users
Attachments:
Pasted Graphic 1.tiff - 2k

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 <da@haywood-associates.co.uk> escribió:

On 29 April 2014 21:34, GESCONSULTOR - Óscar Bou <o.b@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.

Ó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

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.