Search code examples
javaspringhibernatemavenspring-roo

What is the correct procedure for including a Maven-Spring-Roo-Hibernate jar in a Non-Maven-Non-Spring project?


I'm using Spring Roo to generate a bunch of Hibernate objects, inside my unit tests in the same project I can successfully read-write to the database if I do:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath*:/META-INF/spring/applicationContext.xml"})
public class SomeTest extends AbstractJUnit4SpringContextTests {

@Test
public void someTest() throws Exception {
    MyUser myUser = MyUsers.findByUserId(123);
    System.out.println(myUser.getFirstName());
}
....

Now if I do a mvn clean install package and include the jar in an external project and do the same code:

MyUser myUser = MyUsers.findByUserId(123);
System.out.println(myUser.getFirstName());

I get "Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"

I've tried creating a class inside the Spring-Roo-Hibernate project like this and adding ContextConfiguration on top of that:

@Service
@ContextConfiguration(locations = { "classpath*:/META-INF/spring/applicationContext.xml"})
public class SomeClassImpl {

    public MyUser doSomething(){

        MyUser myUser = MyUsers.findByUserId(123);
                return myUser;

    }

}

Now when I call doSomething() in an external project:

public class TestDatabase {
    public static void main(String[] args){

        SomeClassImpl k = new SomeClassImpl();
        k.doSomething();
    }   
}

... I get the same error: "Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"

Looking at the generated AspectJ code:

privileged aspect MyUser_Roo_Jpa_ActiveRecord {

    @PersistenceContext
    transient EntityManager MyUser.entityManager;

    public static final EntityManager MyUser.entityManager() {
        EntityManager em = new MyUser().entityManager;
        if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
        return em;
    }

... I can see that @PersistenceContext is suppose to initialize MyUser.entityManager() which it is not when the project is jarred and included in an external project. How would one go about manually initializing the entityManager ? Or is there another way to initialize the context in the spring project when it's using it as an included library which will initialize the entityManager?


Solution

  • Because the application context don't aware about the model. You are creating the model out of the appcontext. if you get the Model using getBean("MyUser"); some thing like that will work. else auto-wire the model and use that model for your crud operations.

    You can see the following code in MyUser - @PersistenceContext rotected transient EntityManager entityManager; Then only the entityManager object will initialized inside the the Myuser.

       @RunWith(SpringJUnit4ClassRunner.class) 
       @ContextConfiguration(locations = { "classpath*:/META-INF/spring/applicationContext.xml"})
       public class SomeTest extends AbstractJUnit4SpringContextTests {
    
           @Autowired
           MyUser myUser; // use this object for ur crud operations 
    
           @Test
           public void someTest() throws Exception {                
               MyUser otherObject= myUser.findByUserId(123);
               System.out.println(otherObject.getFirstName());
           }
        }