Issue
I'm stumped - I haven't used Hibernate in several years and then, never with Spring Boot. Spring Boot but never with Hibernate or JPA. So i'm trying to figure out how to get this to work for my job - I'm supposed to demo something Monday and if I can get 'this' to work, I'll copy it over to my work laptop and change the details of course. Btw - here's the message I get - I had to shorten it in the title:
"Class org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider does not implement the requested interface javax.persistence.spi.PersistenceProvider"
I have the "main" class - TestWebApplication:
package net.draconia.testWeb;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
@SpringBootApplication(scanBasePackages = {"com.draconia.testWeb.controller"})
public class TestWebApplication
{
@Bean
public DataSource getDatasource()
{
BasicDataSource objDatasource = new BasicDataSource();
objDatasource.setDriverClassName("com.mysql.jdbc.Driver");
objDatasource.setUrl("jdbc:mysql://localhost:3306/Test");
objDatasource.setUsername("root");
objDatasource.setPassword("R3g1n@ M1lL$ 1$ My Qu3eN!");
return(objDatasource);
}
@Bean
public LocalContainerEntityManagerFactoryBean getEntityManagerFactory()
{
LocalContainerEntityManagerFactoryBean objEntityManager = new LocalContainerEntityManagerFactoryBean();
objEntityManager.setDataSource(getDatasource());
objEntityManager.setPackagesToScan(new String[] { "net.draconia.testWeb.beans" });
JpaVendorAdapter objVendorAdapter = new HibernateJpaVendorAdapter();
objEntityManager.setJpaVendorAdapter(objVendorAdapter);
objEntityManager.setJpaProperties(getHibernateProperties());
return(objEntityManager);
}
protected Properties getHibernateProperties()
{
Properties objHibernateProperties = new Properties();
objHibernateProperties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
objHibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
return(objHibernateProperties);
}
@Bean
public JpaTransactionManager getHibernateTransactionManager()
{
JpaTransactionManager objTransactionManager = new JpaTransactionManager();
objTransactionManager.setEntityManagerFactory(getEntityManagerFactory().getObject());
return(objTransactionManager);
}
public static void main(String[] args)
{
SpringApplication.run(TestWebApplication.class, args);
}
}
, the entity bean:
package net.draconia.testWeb.beans;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity(name = "Books")
public class Book
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer miId;
@Column(columnDefinition = "varchar(200) not null", insertable = true, length = 200, name = "BookName", nullable = false, table = "Books", unique = false, updatable = true)
private String msBookName;
@Column(columnDefinition = "varchar(100) not null", insertable = true, length = 100, name="Author", nullable = false, table = "Books", unique = false, updatable = true)
private String msAuthor;
public String getAuthor()
{
if(msAuthor == null)
msAuthor = "";
return(msAuthor);
}
public String getBookName()
{
if(msBookName == null)
msBookName = "";
return(msBookName);
}
public int getId()
{
if(miId == null)
miId = 0;
return(miId);
}
public void setAuthor(final String sAuthor)
{
if(sAuthor == null)
msAuthor = "";
else
msAuthor = sAuthor;
}
public void setBookName(final String sBookName)
{
if(sBookName == null)
msBookName = "";
else
msBookName = sBookName;
}
public void setId(final Integer iId)
{
if(iId == null)
miId = 0;
else
miId = iId;
}
}
, the DAOConcrete class (the interface is just one method which is logical but if you want I'll post that too):
package net.draconia.testWeb.dao;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import net.draconia.testWeb.beans.Book;
@Repository("bookDAO")
public class BookDAOImpl implements BookDAO
{
@Autowired
private EntityManagerFactory mObjEntityManagerFactory;
public List<Book> getAllBooks()
{
EntityManager objEntityManager = getEntityManagerFactory().createEntityManager();
List<Book> lstBooks = objEntityManager.createQuery("from Books", Book.class).getResultList();
return(lstBooks);
}
protected EntityManagerFactory getEntityManagerFactory()
{
return(mObjEntityManagerFactory);
}
}
, and the Controller class for the REST endpoints/MVC Controller:
package net.draconia.testWeb.controllers;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import net.draconia.testWeb.beans.Book;
import net.draconia.testWeb.dao.BookDAO;
@Controller
public class TestController
{
@Autowired
private BookDAO mObjDAO;
@GetMapping("/Books")
public List<Book> getBooks()
{
return(getDAO().getAllBooks());
}
protected BookDAO getDAO()
{
return(mObjDAO);
}
}
The POM file is here just for completeness but I don't think it's necessarily a problem unless I'm missing a dependency:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>net.draconia</groupId>
<artifactId>testWeb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>testWeb</name>
<description>Demo project for Spring Boot</description>
<properties>
<hibernate.version>6.1.0.Final</hibernate.version>
<java.version>11</java.version>
<mysql.version>8.0.29</mysql.version>
<spring.version>5.3.2</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
If you'll note, i'm including a dependency for the Jackson library because the list of books should return as a JSON object. I don't think that's a poblem but just saying - and I could probably have remoed that for this but then when it runs, the list of books would be unintelligible to me getting a response when/if it worked. What am I doing wrong???
Solution
Change hibernate to version 5.6.9.Final:
<hibernate.version>5.6.9.Final</hibernate.version>
Answered By - Davide D'Alto
Answer Checked By - Willingham (JavaFixing Volunteer)