I'm learning Spring MVC, and tried to connect to a database with hibernate. The MVC part worked, and in a separate project, I also could connect and work with the Derby database. But when I tried to put the two together, I failed.
root cause:
java.lang.NoClassDefFoundError: org/apache/derby/jdbc/ClientDriver
hu.pikk.controller.PikkController.test(PikkController.java:42)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219
I don't understand why this is, because I put in the maven file the derby dependency:
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.10.1.1</version>
</dependency>
And I also put the derbyclient.jar file to my classpath:
..Java\jdk1.7.0_45\db\lib\derbyclient.jar
If anyone has any ideas, why it cannot find the class, I would be pleased to know! I tried to search google and stackoverflow for similar errors, but none of the answers were useful.
I tried to create an entitymanager in my controller class in different ways:
@RequestMapping(value={"/","/test"},method = RequestMethod.GET)
public String test(ModelMap model) {
try {
DriverManager.registerDriver(new org.apache.derby.jdbc.ClientDriver());
} catch (SQLException e) {
e.printStackTrace();
}
ClientDriver driver = new ClientDriver();
// factory = Persistence.createEntityManagerFactory("punit"); //Specified JDBC Driver org.apache.derby.jdbc.ClientDriver could not be loaded
// manager = factory.createEntityManager();
// HibernatePersistence hp = new HibernatePersistence();
// factory = hp.createEntityManagerFactory("persistence.xml",null);
if(factory!=null){
manager = factory.createEntityManager();
}else{
System.out.println( "### FACTORY IS NULL ### ");
}
//manager.getTransaction().begin();
//Employee first = manager.find(Employee.class, 1);
//manager.getTransaction().commit();
//model.addAttribute("employee", first);
if(manager==null){
model.addAttribute("message", "Persistence manager is NULL");
}else{
model.addAttribute("message", "Persistence manager is not NULL! Hurray!");
}
return "test";
}
You'll need the dependency for the derby client
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>10.10.1.1</version>
</dependency>
You will also need to make sure it is available in your container. you may wish to follow a spring tutorial for web MVC that covers data access
EDIT
I wouldn't mix dependency resolution. If you're using Maven just stick with it. It's typical to mark the dependency as provided
as your container would have the jar deployed as part of it's setup. For example, if your container is Tomcat you would place the jar in $TOMCAT_HOME/lib
You should also note that Spring provides Factory Beans to create a Session Factory. The Session Factory in turn uses a Data Source to get it' Connections. By wiring your beans this way, Connection management becomes transparent and you can remove that code from your application.
In a typical n-tier application the specifics of data access implementation are encapsulated in a Repository/DAO layer which is then accessed from a Service layer. The Service layer captures business logic and co-ordinates data inputs/retrieval.
Your Controller should only be concerned with capturing/validating input before passing off to the Service layer, and returning output in a format expected by the client (HTML, JSON, XML, etc.)