Announcement Announcement Module
Collapse
No announcement yet.
Spring 3.1, jackrabbit 2 working on DAO layer with se-jcr Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring 3.1, jackrabbit 2 working on DAO layer with se-jcr

    Hi all

    I hope someone can help me with this.
    I am triyin to use se-jcr with out succes let me explain to you.


    What I have?
    I have a Spring MVC 3.1, Jackrabbit 2 (jcr 283)
    Now I am using JCR but I am using it in the controller like follow:

    Code:
    repository = RepositoryAccessServlet.getRepository(request.getSession().getServletContext();
    jcrSession = repository.login(new SimpleCredentials("admin","admin".toCharArray()));

    What I like to do?

    In order to follow a good MVC architecture I like to make all the jackrabbit interaction in the DAO layer and not in the controller layer, there is where I need se-jcr.

    Like is not a good idea to sent the session from the controller to the services and from the services to the DAO I like to get the session in the DAO like follow:

    web.XML first context-param

    Code:
    <context-param>
    	<param-name>contextConfigLocation</param-name>
    	<param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

    applicationContext.xml
    ...spring security stuff
    Code:
    <beans:bean id="repository" class="org.springframework.extensions.jcr.jackrabbit.RepositoryFactoryBean" 
    		p:configuration ="classpath:/repository.xml"
    		p:homeDir="file:./target/repo" >
    	</beans:bean>
    
    	<beans:bean id="jcrSessionFactory" class="org.springframework.extensions.jcr.JcrSessionFactory">
        	<beans:property name="repository" ref="repository"/>
            <beans:property name="credentials">
            	<beans:bean class="javax.jcr.SimpleCredentials">
                	<beans:constructor-arg index="0" value="bogus"/>
                    <beans:constructor-arg index="1" value="pass"/>
                </beans:bean>
        	</beans:property>
     	</beans:bean>
    
    	<beans:bean id="jcrTemplate" class="org.springframework.extensions.jcr.JcrTemplate">
    		<beans:property name="sessionFactory" ref="jcrSessionFactory"/>
    		<beans:property name="allowCreate" value="true"/>
    	</beans:bean>
    As as test I trying to get the session not in the DAO but in the service

    Controller class:
    AbstractRepositoryController has the returnJson method and json declaration as a JsonObject

    Code:
    @Controller
    public class NewController extends AbstractRepositoryController{
    	private ProductDaoImpl daoImpl;
    	  
    	  @Autowired
    	  private NewController(ProductDaoImpl daoImpl){
    		  this.daoImpl = daoImpl;
    	  }
    	
    
    	@RequestMapping("main/test1")
    	protected void test1(HttpServletRequest request, HttpServletResponse response){
    		try {
    			daoImpl.saveSmth();
    			json.put("ok", "todoOk");
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		returnJson(json.toString(), response);
    	}
    }
    Service class:

    Code:
    @Service
    public class ProductDaoImpl extends JcrDaoSupport {
    
        public void saveSmth() throws DataAccessException{
    
            Session session = getSession();
            try {
                    Node root = session.getRootNode();
                    Node sample = root.addNode("sample node");
                    sample.setProperty("sample property", "bla bla");
                    session.save();
            }
            catch (RepositoryException ex) {
                throw convertJcrAccessException(ex);
            }
        }
    }

    What is going on?

    When spring is starting check at NewController and try to get ProductDaoImpl then it fails, with the following output:

    Code:
    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'newController' [.../controllers/main/NewController.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [...services.ProductDaoImpl]: : Error creating bean with name 'productDaoImpl' defined in file [.../services/ProductDaoImpl.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: sessionFactory or jcrTemplate is required;
    The line above is the first line of the exception but kind of say where the problem is, as I understand it ProductDaoImpl could not be created because there are not sessionFactory or jcrTemplate.
    Here is where I do not get the problem, I did define the sessionFactory and jcrTemplate in the applicationContext.xml.

    Then I thought could it be that when spring is starting there is not session? I mean it make sense because is just starting no request have yet arrive to the controller, so what I did was remove the Autowired tag and the code looks like follow:

    Controller class:

    Code:
    @Controller
    public class NewController extends AbstractRepositoryController{
    	
    	
    	private ProductDaoImpl daoImpl;
    	
    
    	@RequestMapping("main/test1")
    	protected void test1(HttpServletRequest request, HttpServletResponse response){
    		daoImpl = new ProductDaoImpl(); 
    		try {
    			daoImpl.saveSmth();
    			json.put("ok", "todoOk");
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		returnJson(json.toString(), response);
    	}
    }
    Service class:
    Code:
    public class ProductDaoImpl extends JcrDaoSupport {
    
        public void saveSmth() throws DataAccessException{
    
            Session session = getSession();
            try {
                    Node root = session.getRootNode();
                    Node sample = root.addNode("sample node");
                    sample.setProperty("sample property", "bla bla");
                    session.save();
            }
            catch (RepositoryException ex) {
                throw convertJcrAccessException(ex);
            }
        }
    }
    And it keeps falling but this time is not at spring start up is when I make the URL request and the controller try to make a ProductDaoImpl instance, the output is the following:

    Code:
    java.lang.NullPointerException
    	at org.springframework.extensions.jcr.support.JcrDaoSupport.getSession(JcrDaoSupport.java:96)
    	at com.test.ok.services.ProductDaoImpl.saveSmth(ProductDaoImpl.java:16)
    	at com.test.ok.controllers.main.NewController.test1(NewController.java:29)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436)
    	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    ...So I do not know what else to do I need your expert help to have this running or undertand what I am doing wrong.

    Thanks a lot!

  • #2
    The spring test test which performance ah?

    Comment


    • #3
      Well the problem was the service, I change it and this is how the service look like:


      Code:
      import javax.jcr.Node;
      import javax.jcr.RepositoryException;
      import javax.jcr.Session;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.dao.DataAccessException;
      import org.springframework.extensions.jcr.JcrCallback;
      import org.springframework.extensions.jcr.JcrTemplate;
      import org.springframework.stereotype.Service;
      
      @Service
      public class ProductDaoImpl {
      	
      	@Autowired
          private JcrTemplate template = null;
      
          public void saveSmth() throws DataAccessException{
      
          	try {
          		
          		template.execute(new JcrCallback() {
      
          	        public Object doInJcr(Session session) throws RepositoryException {
          	            Node root = session.getRootNode();
          	            System.out.println("starting from root node "+ root);
          	            Node sample = root.addNode("sample node");
          	            sample.setProperty("sample property", "bla bla");
          	            System.out.println("saved property " + sample);
          	            session.save();
          	            return null;
          	        }
          	    });
              }
              catch (Exception ex) {
                  ex.printStackTrace();
              }
          }
      }
      the applicationContext.xml look like follow

      Code:
      ...spring security stuff
      <beans:bean id="repository" class="org.springframework.extensions.jcr.jackrabbit.RepositoryFactoryBean" 
      		p:configuration ="classpath:/repository.xml"
      		p:homeDir="file:./target/repo" >
      	</beans:bean>
      
      	<beans:bean id="jcrSessionFactory" class="org.springframework.extensions.jcr.JcrSessionFactory">
          	<beans:property name="repository" ref="repository"/>
              <beans:property name="credentials">
              	<beans:bean class="javax.jcr.SimpleCredentials">
                  	<beans:constructor-arg index="0" value="bogus"/>
                      <beans:constructor-arg index="1" value="pass"/>
                  </beans:bean>
          	</beans:property>
       	</beans:bean>
      
      	<beans:bean id="jcrTemplate" class="org.springframework.extensions.jcr.JcrTemplate">
      		<beans:property name="sessionFactory" ref="jcrSessionFactory"/>
      		<beans:property name="allowCreate" value="true"/>
      	</beans:bean>
      Cheers

      Comment

      Working...
      X