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!