Thursday, September 15, 2011

Spring Roo - Error: One or more exceptions caught, see full set in UmbrellaException#getCauses

Problem

When trying to save a entity in spring roo (using in the web tier gwt) it showed the following error message:

Error: One or more exceptions caught, see full set in UmbrellaException#getCauses

Reason

The declaration of an empty constructor was causing the problem. The roo cause was not identified.

Solution

Remove the constructor. In my case the code was changed from:

public class A {
transient B b;

A(){
this.b = getStub();
}
...
}

to:

public class A {
transient B b= getStub();
...
}



Spring Roo - Error: One or more exceptions caught, see full set in UmbrellaException#getCauses

Problema

Ao tentar salvar uma entidade no spring roo (usando na camada de visão o gwt) apresentou o seguinte problema.

Error: One or more exceptions caught, see full set in UmbrellaException#getCauses

Motivo

A declaração de um construtor vazio estava ocasionando o problema. Mas a causa raiz não foi identificada.

Solução

Remover o construtor vazio. No meu caso foi modificado o código de:

public class A {
transient B b;

A(){
this.b = getStub();
}
...
}

para:

public class A {
transient B b= getStub();
...
}

Wednesday, September 14, 2011

Mock/Stub EntityManager in Spring Roo

Problem

Trying to create unit test to the method persist from a class created in Spring Roo using a stub do the EntityManger that is passed in the constructor as follows:


public class ClassATest {
    @Test
    public void whenPersistShoulCallClassB() throws Exception {
        
        Mockery contexto = new Mockery();
        final ClassB classB = contexto.mock(ClassB.class);
        
        final ClassA classA = 
            new ClassA(getEntityManagerStub(), classB);

        contexto.checking(new Expectations() {{
            one(classB).doSomething(classA);

        }
    });
        classA.persist();
        
        contexto.assertIsSatisfied();
    }

    private EntityManager getEntityManagerStub() {
        return new EntityManager() {
            ...
        }
    }
}
Source from ClassA

public class ClassA {
...

    public ClassA(EntityManager entityManager, ClassB classB) {
        this.entityManager = entityManager;
        this.classB = classB;
    }



    @Transactional
    public void persist() {
        if (this.entityManager == null) this.entityManager = entityManager();
     
        this.entityManager.persist(this);
     
        classB.doSomething(this);
     
    }

...
 }


This test works inside Eclipse, but doesn´t when called by maven, as a result of  mvn jetty:run-exploded.

Reason

Probably Spring Roo is injecting the EntityManager just before the call to the constructor.

Solution

Use of setter injection, as follows:

public class ClassATest {
    @Test
    public void whenPersistShoulCallClassB() throws Exception {
        
        Mockery contexto = new Mockery();
        final ClassB classB = contexto.mock(ClassB.class);
        
        final ClassA classA =
            new ClassA(classB);
        classeA.setEntityManager(getEntityManagerStub());
        
        contexto.checking(new Expectations() {{
            one(classB).doSomething(classeA);

        }
    });
        classeA.persist();
        
        contexto.assertIsSatisfied();
    }

    private EntityManager getEntityManagerStub() {

        return new EntityManager() {
            ...
        }

    }
}


Código da ClasseA


public class ClasseA {
...

    public ClasseA(ClasseB classeB) {
        this.classeB = classeB;
    }


    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }




    @Transactional
    public void persist() {
        if (this.entityManager == null) this.entityManager = entityManager();
      
        this.entityManager.persist(this);
      
        classeB.doSomething(this);
      
    }

...
 }


There must be a more elegant solution that enables the utilization of construction injection. When I have time to research, I will post it.






Mock/Stub do EntityManager no Spring Roo

Problema

Ao tentar criar testes de unidade para o método persist de uma classe criada pelo Spring Roo, tentei utilizar um Stub para o EntityManager da seguinte forma:



public class ClasseATest {
    @Test
    public void aoPersistirDeveriaChamarClasseB() throws Exception {
        
        Mockery contexto = new Mockery();
        final ClasseB classeB = contexto.mock(ClasseB.class);
        
        final ClasseA classeA = 
            new ClasseA(getEntityManagerStub(), classeB);

        contexto.checking(new Expectations() {{
            one(classeB).fazerAlgo(classeA);

        }
    });
        classeA.persist();
        
        contexto.assertIsSatisfied();
    }

    private EntityManager getEntityManagerStub() {
        return new EntityManager() {
            ...
        }
    }
}
Código da ClasseA

public class ClasseA {
...

    public ClasseA(EntityManager entityManager, ClasseB classeB) {
        this.entityManager = entityManager;
        this.classeB = classeB;
    }



    @Transactional
    public void persist() {
        if (this.entityManager == null) this.entityManager = entityManager();
     
        this.entityManager.persist(this);
     
        classeB.fazerAlgo(this);
     
    }

...
 }


O teste funcionava quando era executado dentro de Eclipse, mas falhava quando era executado via maven, no momento da execução do mvn jetty:run-exploded.


Motivo

Provavelmente o spring roo está injetando o EntityManager logo após a chamada ao constructor.

Solução

Utilizar setter injection, como mostrado abaixo:


public class ClasseATest {
    @Test
    public void aoPersistirDeveriaChamarClasseB() throws Exception {
        
        Mockery contexto = new Mockery();
        final ClasseB classeB = contexto.mock(ClasseB.class);
        
        final ClasseA classeA =
            new ClasseA(classeB);
        classeA.setEntityManager(getEntityManagerStub());
        
        contexto.checking(new Expectations() {{
            one(classeB).fazerAlgo(classeA);

        }
    });
        classeA.persist();
        
        contexto.assertIsSatisfied();
    }

    private EntityManager getEntityManagerStub() {

        return new EntityManager() {
            ...
        }

    }
}


Código da ClasseA


public class ClasseA {
...

    public ClasseA(ClasseB classeB) {
        this.classeB = classeB;
    }


    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }




    @Transactional
    public void persist() {
        if (this.entityManager == null) this.entityManager = entityManager();
      
        this.entityManager.persist(this);
      
        classeB.fazerAlgo(this);
      
    }

...
 }


Provavelmente deve existir uma solução mais elegante, que permita a utilização da injeção da dependência no construtor. Quando tiver tempo vou pesquisar e bloggar a solução.