I am new in Hibernate and facing some problem during execution first programme:
java.lang.ClassNotFoundException: Could not load requested class : com.mysql.jdbc.Driver. I was following tutorial about Hibernate, did everything same(even copied everything and tried to run).I've been searching for answers all over the internet, but none of them helped me.
persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<class>com.newthinktank.JEETut3.Customer</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/test4" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="myPassword!" />
</properties>
</persistence-unit>
</persistence>
pom.xml:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.newthinktank</groupId>
<artifactId>JEETut3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>JEETut3</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.4.1.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
*Customer:*
package com.newthinktank.JEETut3;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "customer")
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private int id;
#Column(name = "firstName", nullable = false)
private String fName;
#Column(name = "lastName", nullable = false)
private String lName;
public int getID() {
return id;
}
public void setID(int id) {
this.id = id;
}
public String getFName() {
return fName;
}
public void setFName(String fName) {
this.fName = fName;
}
public String getLName() {
return lName;
}
public void setLName(String lName) {
this.lName = lName;
}
}
TestSystem:
package com.newthinktank.JEETut3;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.NoResultException;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
public class TestSystem {
private static final EntityManagerFactory ENTITY_MANAGER_FACTORY = Persistence
.createEntityManagerFactory("JEETut3");
public static void main(String[] args) {
addCustomer(1, "Sue", "Smith");
addCustomer(2, "Sam", "Smith");
addCustomer(3, "Sid", "Smith");
addCustomer(4, "Sally", "Smith");
getCustomer(1);
getCustomers();
changeFName(4, "Mark");
deleteCustomer(3);
ENTITY_MANAGER_FACTORY.close();
}
public static void addCustomer(int id, String fname, String lname) {
EntityManager em = ENTITY_MANAGER_FACTORY.createEntityManager();
EntityTransaction et = null;
try {
et = em.getTransaction();
et.begin();
Customer cust = new Customer();
cust.setID(id);
cust.setFName(fname);
cust.setLName(lname);
em.persist(cust);
et.commit();
} catch (Exception ex) {
if (et != null) {
et.rollback();
}
ex.printStackTrace();
} finally {
em.close();
}
}
public static void getCustomer(int id) {
EntityManager em = ENTITY_MANAGER_FACTORY.createEntityManager();
String query = "SELECT c FROM Customer c WHERE c.id = :custID";
TypedQuery<Customer> tq = em.createQuery(query, Customer.class);
tq.setParameter("custID", id);
Customer cust = null;
try {
cust = tq.getSingleResult();
System.out.println(cust.getFName() + " " + cust.getLName());
} catch (NoResultException ex) {
ex.printStackTrace();
} finally {
em.close();
}
}
public static void getCustomers() {
EntityManager em = ENTITY_MANAGER_FACTORY.createEntityManager();
String strQuery = "SELECT c FROM Customer c WHERE c.id IS NOT NULL";
TypedQuery<Customer> tq = em.createQuery(strQuery, Customer.class);
List<Customer> custs;
try {
custs = tq.getResultList();
custs.forEach(cust -> System.out.println(cust.getFName() + " " + cust.getLName()));
} catch (NoResultException ex) {
ex.printStackTrace();
} finally {
em.close();
}
}
public static void changeFName(int id, String fname) {
EntityManager em = ENTITY_MANAGER_FACTORY.createEntityManager();
EntityTransaction et = null;
Customer cust = null;
try {
et = em.getTransaction();
et.begin();
cust = em.find(Customer.class, id);
cust.setFName(fname);
em.persist(cust);
et.commit();
} catch (Exception ex) {
if (et != null) {
et.rollback();
}
ex.printStackTrace();
} finally {
em.close();
}
}
public static void deleteCustomer(int id) {
EntityManager em = ENTITY_MANAGER_FACTORY.createEntityManager();
EntityTransaction et = null;
Customer cust = null;
try {
et = em.getTransaction();
et.begin();
cust = em.find(Customer.class, id);
em.remove(cust);
et.commit();
} catch (Exception ex) {
if (et != null) {
et.rollback();
}
ex.printStackTrace();
} finally {
em.close();
}
}
}
Error:
lip 24, 2020 1:42:49 PM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [name: JEETut3]
lip 24, 2020 1:42:49 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.4.3.Final}
lip 24, 2020 1:42:49 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
lip 24, 2020 1:42:49 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:175)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:118)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:900)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:931)
at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at com.newthinktank.JEETut3.TestSystem.<clinit>(TestSystem.java:15)
Caused by: org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [com.mysql.jdbc.Driver]
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:136)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.loadDriverIfPossible(DriverManagerConnectionProviderImpl.java:149)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.buildCreator(DriverManagerConnectionProviderImpl.java:105)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.buildPool(DriverManagerConnectionProviderImpl.java:89)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:73)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:107)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:246)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
... 14 more
Caused by: java.lang.ClassNotFoundException: Could not load requested class : com.mysql.jdbc.Driver
at org.hibernate.boot.registry.classloading.internal.AggregatedClassLoader.findClass(AggregatedClassLoader.java:210)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:416)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:133)
... 26 more
Does anyone know how to resolve problem?
I have tested your code and the problem is in the mysql maven dependency you need to remove scope provided because you are saying it will be provided while running but that is not the case.
These are the changes I did to make it run.
Remove provided scope to mysql maven dependency
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
Change your jdbc driver in persistence.xml as the one you use is deprecated
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
You are also missing a mandatory part of persistence.xml code
<persistence-unit name="JEETut3" transaction-type="RESOURCE_LOCAL">
I have also added the dialect of database in the persistence.xml
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
In case you want the tables to be created automatically on each execution you can add
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
In summary this is the persistence I used
<persistence-unit name="JEETut3" transaction-type="RESOURCE_LOCAL">
<class>com.newthinktank.JEETut3.Customer</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/test4"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="myPassword!"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
</properties>
</persistence-unit>
This is the result you will get in the database
I hope this helps you solving your issue
Related
I try to make use a Database system without have to run a separate database program.
I decided to use Hibernate SQLite. And I'm getting desperate here.
can someone pls tell me what i am doing whrong, or where i can find more help? I Faild with google, and ChatGPT was as always not helpfull to.
And for every one how try to convince me to use for example MariaDB, no. I need it to be one java application. Not more, not less...
src\main\resources\hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- <property name="hibernate.connection.url">jdbc:sqlite:path/to/your/database.db</property> -->
<property name="hibernate.connection.driver_class">org.sqlite.JDBC</property>
<property name="hibernate.connection.url">jdbc:sqlite:database.db</property>
<property name="hibernate.dialect">org.hibernate.dialect.SQLiteDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<mapping class="de.minetrain.kekbot.database.test.Person"/>
</session-factory>
</hibernate-configuration>
src\main\resources\persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd" version="2.2">
<persistence-unit name="my-persistence-unit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>de.minetrain.kekbot.database.test.Person</class>
<!-- <class>com.example.MyOtherEntity</class> -->
<properties>
<property name="hibernate.connection.driver_class" value="org.sqlite.JDBC" />
<!-- <property name="hibernate.connection.url" value="jdbc:sqlite:path/to/your/database.db" /> -->
<property name="hibernate.connection.url" value="jdbc:sqlite:database.db" />
<property name="hibernate.connection.username" value="" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLiteDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<!-- <property name="hibernate.show_sql" value="true" /> -->
</properties>
</persistence-unit>
</persistence>
pom.xml
</ependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.1.Final</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.34.0</version>
</dependency>
</dependencies>
HibernateUtil class:
package de.minetrain.kekbot.database.test;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HibernateUtil {
private static final Logger logger = LoggerFactory.getLogger(HibernateUtil.class);
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e) {
logger.error("Dant find class: ",e);
}
try {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml"); // may wrong?
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
return configuration.buildSessionFactory(builder.build());
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Entity class:
package de.minetrain.kekbot.database.test;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Person {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
private int age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
And the class i try to whrite into the database:
package de.minetrain.kekbot.database.test;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
public class Database {
public static void test(){
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
// Verwenden Sie die Session, um Datenbankoperationen auszuführen
// session.close();
Transaction tx = null;
try {
tx = session.beginTransaction();
Person person = new Person();
person.setName("Max Mustermann");
person.setAge(30);
session.save(person);
tx.commit();
} catch (HibernateException ex) {
if (tx != null) {
tx.rollback();
}
ex.printStackTrace();
} finally {
session.close();
}
}
}
I just wanna lern to use SQLite, and try to Whrite a new person object into a database file.
Errors:
[20:00:15] >> WARN << [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator] - HHH000342: Could not obtain connection to query metadata java.lang.IllegalStateException: Cannot get a connection as the driver manager is not properly initialized
Initial SessionFactory creation failed.org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
Caused by: org.hibernate.boot.registry.selector.spi.StrategySelectionException: Unable to resolve name [org.hibernate.dialect.SQLiteDialect] as strategy [org.hibernate.dialect.Dialect]
Caused by: org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [org.hibernate.dialect.SQLiteDialect]
Caused by: java.lang.ClassNotFoundException: Could not load requested class : org.hibernate.dialect.SQLiteDialect
I've managed to change the Exeptions. With the help from #andrewJames I found out, that I have to use a dialect, which I didn't know. I also noticed that I am using old versions of Hibernate and co.
And sorry in advance, for every experienced coder how gets headaches from my stupidity. I am not new to coding, but I am very new to databases and dealing with dependency's outside from just API package things. I tried to google as much as I could find, and testing every thing I could. But I ended up having to ask again. I am very sorry.
Iive changed stuff around and now have this pom.xml:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.1.6.Final</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.40.0.0</version>
</dependency>
<dependency>
<groupId>com.github.gwenn</groupId>
<artifactId>sqlite-dialect</artifactId>
<version>0.1.2</version>
</dependency>
I've changed the dialect in the hibernate.cfg.xml:
<property name="hibernate.dialect">org.sqlite.hibernate.dialect.SQLiteDialect</property>
persistence.xml:
<property name="hibernate.dialect" value="org.sqlite.hibernate.dialect.SQLiteDialect" />
However, now I get the benefit of dealing with this exception:
[00:07:48] >> INFO << [org.hibernate.Version] - HHH000412: Hibernate ORM core version 6.1.6.Final
Initial SessionFactory creation failed.java.util.ServiceConfigurationError: org.hibernate.boot.spi.MetadataBuilderInitializer: Provider org.sqlite.hibernate.dialect.SQLiteMetadataBuilderInitializer could not be instantiated
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.util.ServiceConfigurationError: org.hibernate.boot.spi.MetadataBuilderInitializer: Provider org.sqlite.hibernate.dialect.SQLiteMetadataBuilderInitializer could not be instantiated
Caused by: java.lang.NoClassDefFoundError: org/hibernate/dialect/function/SQLFunction
Caused by: java.lang.ClassNotFoundException: org.hibernate.dialect.function.SQLFunction
I am using jdk 13 but I want to create entity and write to database its.
and I added project->run configurations->arguments->VM Arguments
--add-modules java.xml.bind
then I ran the project but , I am getting this error :
Error occurred during initialization of boot layer
java.lang.module.FindException: Module java.xml.bind not found
I dont know, I am getting error why.I suppose my jdk is problem.But I dont know exactly.what should I do?
Test.java
package com.kerem.blog;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class Test {
public static void main(String[] args) {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("MyPersistenceUnit");
EntityManager manager = factory.createEntityManager();
Data data = new Data();
data.setDataName("Kerem");
data.setDataValue(23.2);
manager.getTransaction().begin();
manager.persist(data);
manager.getTransaction().commit();
manager.close();
}
}
Data.java
package com.kerem.blog;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Data {
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
private long dataId;
private String dataName;
private double dataValue;
public long getDataId() {
return dataId;
}
public void setDataId(long dataId) {
this.dataId = dataId;
}
public String getDataName() {
return dataName;
}
public void setDataName(String dataName) {
this.dataName = dataName;
}
public double getDataValue() {
return dataValue;
}
public void setDataValue(double dataValue) {
this.dataValue = dataValue;
}
}
persistence.xml
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="MyPersistenceUnit">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.driver"
value="com.mysql.cj.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/testdb?useSSL=false&useLegacyDatetimeCode=false&serverTimezone=Turkey" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password"
value="kerem2112" />
<property
name="javax.persistence.schema-generation.database.action"
value="create" />
</properties>
</persistence-unit>
</persistence>
pom.xml
<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>
<groupId>com.keremsarmis</groupId>
<artifactId>blogbasic</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.6.Final</version>
</dependency>
</dependencies>
</project>
I am using hibernate in my Java EE application in combination with my Wildfly server to persist my Classes in a mysql Database.
So far this works fine but now I am writing unit tests and I am getting crazy about some error which I get.
I would like to test my DAO-Layer in my Unit-Tests but I get these errors:
Caused by: org.hibernate.engine.jndi.JndiException: Error parsing JNDI name [java:/MySqlDS]
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
my persistence.xml ist this:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="primary">
<jta-data-source>java:/MySqlDS</jta-data-source>
<class>org.se.bac.data.Employee</class>
<properties>
<!-- Properties for Hibernate -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/empdb?useSSL=false"/>
<property name="hibernate.connection.username" value="student"/>
<property name="hibernate.connection.password" value="student"/>
<!--
SQL stdout logging
-->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="use_sql_comments" value="true"/>
</properties>
</persistence-unit>
</persistence>
So, Here I am using a jta-data-source> as you can see.
If I remove this line my tests are going fine! But I can not build my project with maven anymore.
Error:
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
Caused by: org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [com.mysql.jdbc.Driver]
Caused by: java.lang.ClassNotFoundException: Could not load requested class : com.mysql.jdbc.Driver"}}
He can not find the datasource because I removed the line in my persistence.xml
How can I manage to get both run in my application. The tests and of course the maven build?
Here is my test: (Setup is already causing the error):
package org.se.bac.data.dao;
import java.util.List;
import javax.persistence.EntityManager;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.se.bac.data.model.Employee;
public class EmployeeDAOTest
{
private static final JdbcTestHelper JDBC_HELPER = new JdbcTestHelper();
private final static JpaTestHelper JPA_HELPER = new JpaTestHelper();
private EntityManager em = JPA_HELPER.getEntityManager("primary");
private EmpDAO dao;
#BeforeClass
public static void init()
{
JDBC_HELPER.executeSqlScript("sql/test/dropEmployeeTable.sql");
JDBC_HELPER.executeSqlScript("sql/test/createEmployeeTable.sql");
}
#AfterClass
public static void destroy()
{
//JDBC_HELPER.executeSqlScript("sql/test/dropEmployeeTable.sql");
}
#Before
public void setUp()
{
JDBC_HELPER.executeSqlScript("sql/test/dropEmployeeTable.sql");
JDBC_HELPER.executeSqlScript("sql/test/createEmployeeTable.sql");
dao = new EmpDAOImpl();
dao.setEm(em);
JPA_HELPER.txBegin();
Employee emp2 = new Employee();
emp2.setFirstname("Max");
emp2.setLastname("Muster");
emp2.setHiredate("23-12-1991");
dao.insert(emp2);
}
And JPAHELPER Class:
package org.se.bac.data.dao;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class JpaTestHelper
{
/*
* Property: persistenceUnitName
*/
private String persistenceUnitName;
public String getPersistenceUnitName()
{
return persistenceUnitName;
}
public void setPersistenceUnitName(String persistenceUnitName)
{
if(persistenceUnitName == null || persistenceUnitName.length() == 0)
throw new IllegalArgumentException("Illegal parameter persistenceUnitName = " + persistenceUnitName);
this.persistenceUnitName = persistenceUnitName;
}
/*
* Get an instance of the EntityManagerFactory.
*/
protected EntityManagerFactory getEnityManagerFactory()
{
if(persistenceUnitName == null)
throw new IllegalStateException("PersistenceUnitName must be set!");
return Persistence.createEntityManagerFactory(persistenceUnitName);
}
/*
* Manage an EntityManager.
*/
private EntityManager em;
public EntityManager getEntityManager()
{
if(em == null)
{
em = getEnityManagerFactory().createEntityManager();
}
return em;
}
public EntityManager getEntityManager(String persistenceUnitName)
{
setPersistenceUnitName(persistenceUnitName);
return getEntityManager();
}
public void closeEntityManager()
{
if(em != null)
em.close();
}
/*
* Handle Transactions
*/
protected void txBegin()
{
EntityTransaction tx = em.getTransaction();
tx.begin();
}
protected void txCommit()
{
EntityTransaction tx = em.getTransaction();
if(tx.getRollbackOnly())
{
tx.rollback();
}
else
{
tx.commit();
}
}
protected void txRollback()
{
EntityTransaction tx = em.getTransaction();
tx.rollback();
}
}
and my DAO:
package org.se.bac.data.dao;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.se.bac.data.model.Employee;
class EmpDAOImpl // package private
implements EmpDAO
{
#PersistenceContext
private EntityManager em;
/*
* CRUD methods
*/
public Employee findById(int id)
{
System.out.println("empdaoimpl ID " + id);
return em.find(Employee.class, id);
}
public EntityManager getEm() {
return em;
}
public void setEm(EntityManager em) {
this.em = em;
}
}
Wildfly Datasource:
<datasources>
<datasource jta="true" jndi-name="java:/MySqlDS" pool-name="MySqlDS" enabled="true" use-ccm="false">
<connection-url>jdbc:mysql://localhost:3306/empdb?useSSL=false</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<driver>mysql-connector-java-5.1.44-bin.jar_com.mysql.jdbc.Driver_5_1</driver>
<security>
<user-name>student</user-name>
<password>student</password>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker"/>
<background-validation>true</background-validation>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter"/>
</validation>
</datasource>
</datasources>
He can not find the datasource because I removed the line in my persistence.xml
How can I manage to get both run in my application.
The problem is that the data source is managed by Wildfly which is not available on your test environment. So what you could do is define two separate persistence units (one for your production code and the other for the test) as follows:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="primary">
<jta-data-source>java:/MySqlDS</jta-data-source>
<properties>
<!-- Properties for Hibernate -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<!-- SQL stdout logging -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="use_sql_comments" value="true"/>
</properties>
</persistence-unit>
<persistence-unit name="testPU" transaction-type="RESOURCE_LOCAL">
<class>org.se.bac.data.Employee</class>
<properties>
<!-- Properties for Hibernate -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/empdb?useSSL=false"/>
<property name="hibernate.connection.username" value="student"/>
<property name="hibernate.connection.password" value="student"/>
<!-- SQL stdout logging -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="use_sql_comments" value="true"/>
</properties>
</persistence-unit>
</persistence>
and then in your EmployeeDAOTest class modify the following line as:
private EntityManager em = JPA_HELPER.getEntityManager("testPU");
Note:
I removed the JDBC connection properties from the primary persistence unit because you don't need them as you already have the data source there on Wildfly.
i am getting this error when I want to run the following code:
package HIndexSaar.HIndex;
public class AppHibernate {
public static void main(String[] args){
HibernateManager mng = new HibernateManager();
mng.addPerson("H H", "Uni Saarland");
mng.addPerson("Bernd Finkbeiner", "Uni Saarland");
mng.addUniversity("Saarland University");
}
}
My HibernateManager class:
package HIndexSaar.HIndex;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class HibernateManager {
private static SessionFactory ourSessionFactory;
private static ServiceRegistry serviceRegistry;
public HibernateManager(){
try {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
ourSessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
/**
* adds a person to the database.
* #param name: the name of the person
* #param affiliation: the university of the person
* #return the created ID
*/
public Integer addPerson(String name, String affiliation){
Transaction tx = null;
Integer personID = null;
try (Session session = ourSessionFactory.openSession()) {
tx = session.beginTransaction();
Person p = new Person(name, affiliation);
personID = (Integer) session.save(p);
tx.commit();
} catch (HibernateException e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
}
return personID;
}
/**
* adds a university to the database.
* #param name: the name of the university
* #return the id of the newly created university
* */
public Integer addUniversity(String name){
Transaction trans = null;
Integer uniID = null;
try (Session session = ourSessionFactory.openSession()) {
trans = session.beginTransaction();
University uni = new University(name);
uniID = (Integer) session.save(uni);
trans.commit();
} catch (HibernateException e) {
if (trans != null) {
trans.rollback();
}
e.printStackTrace();
}
return uniID;
}
/**
* adds a publication to the database.
* #param name: the name of the publication
* #param author: the author of the publication
* #return the generated ID
*/
public Integer addPublication(String name, String author){
Transaction trans = null;
Integer pubID = null;
try (Session session = ourSessionFactory.openSession()) {
trans = session.beginTransaction();
Publication p = new Publication(name, author);
pubID = (Integer) session.save(p);
trans.commit();
} catch (HibernateException e) {
if (trans != null) {
trans.rollback();
}
e.printStackTrace();
}
return pubID;
}
}
And my hibernate.cfg.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="HIndex Session">
<!-- Database connection settings -->
<property name="connection.driver:class">org.postgreSQL.Driver</property>
<property name="connection.url">jdbc:postgresql://localhost/HIndex</property>
<property name="hibernate.connection.username">index_user</property>
<property name="hibernate.connection.password">password</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL Dialect -->
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQL82Dialect</property>
<!-- Assume test is the database name -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<!-- Names the annotated entity class -->
<mapping class="HIndexSaar.HIndex.Person"/>
<mapping class="HIndexSaar.HIndex.University"/>
<mapping class="HIndexSaar.HIndex.Publication"/>
</session-factory>
</hibernate-configuration>
And the pom.xml
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>HIndexSaar</groupId>
<artifactId>HIndex</artifactId>
<version>Version 0.2</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<packaging>jar</packaging>
<name>HIndex</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<!-- jsoup HTML parser library # http://jsoup.org/ -->
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.8.3</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4.1207</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.7.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.5.6-Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.0-RC1</version>
</dependency>
</dependencies>
</project>
The error is shown at the "tx.rollback();" line:
catch (HibernateException e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
}
I do not use multiple threads anywhere, so what am I missing?
From the docs for ResourceClosedException:
Indicates an attempt was made to use a closed resource (Session,
SessionFactory, etc).
Now, when using "try with resources", the documentation says:
Note: A try-with-resources statement can have catch and finally blocks
just like an ordinary try statement. In a try-with-resources
statement, any catch or finally block is run after the resources
declared have been closed.
So by the time you call rollback() the Session will already have been closed.
The simplest solution here would be to move your existing catch block to an inner try/catch block around the transaction-management code, e.g.:
try (Session session = ourSessionFactory.openSession()) {
try {
tx = session.beginTransaction();
Person p = new Person(name, affiliation);
personID = (Integer) session.save(p);
tx.commit();
}
catch (HibernateException e) {
if (tx != null) {
tx.rollback();
}
}
}
This ensures that the Session only gets closed once you've (at least) requested rollback.
I'm trying to create a test for a file that's using a jdbc resource. Regular tests work fine throughout the project, except for when I'm trying to test something that is using an entity manager. I think I'm missing something simple here and would appreciate any help.
Here's the error.
Feb 27, 2012 3:04:44 PM com.sun.enterprise.v3.server.ApplicationLifecycle deploy
SEVERE: javax.naming.NamingException: Lookup failed for 'jdbc/foundation' in SerialContext[myEnv={com.sun.enterprise.connectors.jndisuffix=__pm, java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: foundation not found]
java.lang.RuntimeException: javax.naming.NamingException: Lookup failed for 'jdbc/foundation' in SerialContext[myEnv={com.sun.enterprise.connectors.jndisuffix=__pm, java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: foundation not found]
Here's some of the troubleshooting steps I've taken:
Added the glassfish extras to the maven POM
I have placed the persistence file in both the /main/resources and /test/resources folders.
I have tried adding properties to the context object in the #BeforeClass method in the DonationsFacadeTest file along with about a million other configurations similar to the one below.
Environment Info:
Using Netbeans 7.0.1
Maven Project
Glassfish 3.1
DonationsFacade.java - This class is using a facade pattern to provide indirect access to JPA entities.
#Stateless
public class DonationsFacade extends AbstractFacade<Donations> {
#PersistenceContext(unitName = "FoundationPU")
private EntityManager em;
protected EntityManager getEntityManager() {
return em;
}
public DonationsFacade() {
super(Donations.class);
}
public boolean setPaid(int id, String transId)
{
try{
Donations don = em.find(Donations.class, id);
don.setStatus("Paid");
don.setConfirmationnumber(transId);
em.persist(don);
em.flush();
return true;
}
catch(Exception ex)
{
return false;
}
}
Test File - Just trying to write a simple test to to verify the data.
public class DonationsFacadeTest {
#Test
public void testSetPaid() throws Exception {
int id = 1;
String transId = "123";
EJBContainer ejbC = EJBContainer.createEJBContainer();
Context ctx = ejbC.getContext();
DonationsFacade instance = (DonationsFacade)ctx.lookup("java:global/classes/DonationsFacade");
boolean expResult = false;
boolean result = instance.setPaid(id, transId);
assertEquals(expResult, result);
ejbC.close();
}
}
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"...>
<persistence-unit name="FoundationPU" transaction-type="JTA">
<jta-data-source>jdbc/foundation</jta-data-source>
<properties/>
</persistence-unit>
</persistence>
glassfish-resources.xml
<resources>
<jdbc-resource enabled="true" jndi-name="jdbc/foundation" object-type="user" pool-name="mysql_foundation_rootPool">
<description/>
</jdbc-resource>
<jdbc-connection-pool allow-non-component-callers="false"
associate-with-thread="false"
connection-creation-retry-attempts="0"
connection-creation-retry-interval-in-seconds="10"
connection-leak-reclaim="false"
connection-leak-timeout-in-seconds="0"
connection-validation-method="table"
datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource"
fail-all-connections="false" idle-timeout-in-seconds="300"
is-connection-validation-required="false"
is-isolation-level-guaranteed="true"
lazy-connection-association="false"
lazy-connection-enlistment="false"
match-connections="false"
max-connection-usage-count="0"
max-pool-size="32"
max-wait-time-in-millis="60000"
name="connectionPool"
non-transactional-connections="false"
ping="false"
pool-resize-quantity="2"
pooling="true"
res-type="javax.sql.DataSource"
statement-cache-size="0"
statement-leak-reclaim="false"
statement-leak-timeout-in-seconds="0"
statement-timeout-in-seconds="-1"
steady-pool-size="8"
validate-atmost-once-period-in-seconds="0"
wrap-jdbc-objects="true">
<property name="URL" value="jdbc:mysql://localhost:3306/foundation"/>
<property name="User" value="root"/>
<property name="Password" value="thepassword"/>
</jdbc-connection-pool>
</resources>
Again, thanks for the help, very much appreciated.
Figured out the answer here. I basically injected a entitymanager into the class. Hopefully this is helpful to someone who is trying to do this same thing.
public class DonationsFacadeTest {
private EntityManager em;
private EntityTransaction tx;
DonationsFacade donations;
public DonationsFacadeTest() {
}
#Before
public void setUpClass() throws Exception {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("Foundation2");
em = emf.createEntityManager();
tx = em.getTransaction();
this.donations = new DonationsFacade();
this.donations.em = em;
}
/**
* Test of setPaid method, of class DonationsFacade.
*/
#Test
public void testSetPaid() throws Exception {
int id = 1;
String transId = "123";
boolean expResult = false;
boolean result = donations.setPaid(id, transId);
assertEquals(expResult, result);
}
}
Modified the persistence.xml file appropriately.
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" ... >
<persistence-unit name="Foundation2" transaction-type="RESOURCE_LOCAL">
<class>org.scmc.foundation.session.DonationsFacadeTest</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/foundation"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="password"/>
</properties>
</persistence-unit>
And finally added the appropriate driver to the POM file.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>