I am learning Java EE and for 2 days already I've been struggling with configuration of Hibernate to work with MySQL database on a TomEE server in a simple Java EE web application.
Hibernate version: 5.4.10.Final (core and entity-manager dependencies)
Java EE API: 8.0
MySQL version: 8.0.19
TomEE version: 8.0.1 (TomEE Embedded in tomee-embedded-maven-plugin)
I have 2 simple entities: Car and Seat, with the uni-directional #OneToMany relation from Car to Seat(s). Color and EngineType are plain enums, while Specification is a value object for these 2 enums). NOTE: FetchType.EAGER is used in the #OneToMany for learning purposes, I am familiar that this is not a good solution normally.
When I try to configure the persistence.xml file, alghouth specifying everything "as for MySQL", it seems that Hibernate still uses the default HSQLDB syntax/dialect/engine and as a result, I recieve errors during schema creation:
[INFO] TomEE embedded started on localhost:8080
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect
Hibernate: alter table Seat drop foreign key FKkkm9pdx9e1t9jva76n9tqhhqv
mar 06, 2020 1:48:31 PM org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl handleException
WARN: GenerationTarget encountered exception accepting command : Error executing DDL "alter table Seat drop foreign key FKkkm9pdx9e1t9jva76n9tqhhqv" via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table Seat drop foreign key FKkkm9pdx9e1t9jva76n9tqhhqv" via JDBC Statement
(...)
Caused by: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: PUBLIC.SEAT
(...)
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: PUBLIC.SEAT // what is going on here???
and for later Hibernate SQL commands while creating DDL, I have also:
Hibernate: create table Car (identifier bigint not null auto_increment, color varchar(255), engineType varchar(255), primary key (identifier)) engine=InnoDB
mar 06, 2020 1:48:31 PM org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl handleException
WARN: GenerationTarget encountered exception accepting command : Error executing DDL "create table Car (identifier bigint not null auto_increment, color varchar(255), engineType varchar(255), primary key (identifier)) engine=InnoDB" via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table Car (identifier bigint not null auto_increment, color varchar(255), engineType varchar(255), primary key (identifier)) engine=InnoDB" via JDBC Statement
(...)
Caused by: java.sql.SQLSyntaxErrorException: unexpected token: AUTO_INCREMENT
(...)
Caused by: org.hsqldb.HsqlException: unexpected token: AUTO_INCREMENT // definitely something messed up, this is a correct MySQL token
When I omit all "MySQL stuff" (driver and dialect), and make Hibernate use default HSQLDB, it works fine... The DDL for HSQLDB is created well.
I tried many different configurations and replacements googling it over the web and SO, but not found any hint why Hibernate still uses non-MySQL syntax (but I am not 100% sure that this is the direct cause of the issue).
I attempted to specify the datasource in resources.xml file under webapp, but it doesn't change anything. Additionally, I checked if HSQLDB could be excluded from Maven build, but it ships with hibernate-core, so it's not easily achievable and perhaps could also not help.
I have previously used Hibernate with Spring and SpringBoot, but with Java EE I am totally lost here, that's why I asked the question.
Could anyone help with the issue and give some advices on the correct configuration of all this?
My persistence.xml under resources/META-INF looks like this:
<?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" version="2.2"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<persistence-unit name="my-persistence-unit" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:openejb/Resource/myJtaDatabase</jta-data-source>
<!-- Entity classes -->
<class>com.example.javaeecourse.entity.Car</class>
<class>com.example.javaeecourse.entity.Seat</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/javaeecourse?serverTimezone=UTC" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="admin" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="tomee.jpa.factory.lazy" value="true" />
<!--<property name="tomee.jpa.cdi=false" value="false" />-->
</properties>
</persistence-unit>
</persistence>
Car entity:
package com.example.javaeecourse.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
import static com.example.javaeecourse.entity.Car.FIND_ALL;
#Getter
#Setter
#Entity
#Table(name = "cars")
#NamedQuery(name = FIND_ALL, query = "SELECT car FROM Car car")
#NoArgsConstructor
public class Car {
public static final String FIND_ALL = "Car.findAll";
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long identifier;
#Enumerated(EnumType.STRING)
private Color color;
#Enumerated(EnumType.STRING)
private EngineType engineType;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "car", nullable = false)
private Set<Seat> seats = new HashSet<>();
}
Seat entity:
package com.example.javaeecourse.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
#Entity
#Table(name = "seats")
#NoArgsConstructor
#Getter
#Setter
public class Seat {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String seatMaterial;
public Seat(String seatMaterial) {
this.seatMaterial = seatMaterial;
}
}
CarManufacturer class (#Stateless EJB, where EntityManager is called):
package com.example.javaeecourse.boundary;
import com.example.javaeecourse.control.CarFactory;
import com.example.javaeecourse.entity.Car;
import com.example.javaeecourse.entity.CarCreatedEvent;
import com.example.javaeecourse.entity.Specification;
import javax.ejb.Stateless;
import javax.enterprise.event.Event;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
#Stateless
public class CarManufacturer {
#Inject
CarFactory carFactory;
#Inject
Event<CarCreatedEvent> carCreatedEvent;
#PersistenceContext
EntityManager entityManager;
public Car manufactureCar(Specification specification) {
Car car = carFactory.createCar(specification);
entityManager.persist(car);
carCreatedEvent.fire(new CarCreatedEvent(car.getIdentifier()));
return car;
}
public List<Car> retrieveCars() {
return entityManager.createNamedQuery(Car.FIND_ALL, Car.class).getResultList();
}
}
CarFactory class, which instantiates the entity:
package com.example.javaeecourse.control;
import com.example.javaeecourse.entity.*;
import javax.inject.Inject;
public class CarFactory {
#Inject
#DefaultCarColor
Color randomCarColor;
#Inject
#DefaultCarEngineType
EngineType randomCarEngineType;
public Car createCar(Specification specification) {
Car car = new Car();
car.setColor(specification.getColor() == null ? randomCarColor : specification.getColor());
car.setEngineType(specification.getEngineType() == null ? randomCarEngineType : specification.getEngineType());
Seat seat = new Seat("Leather");
car.getSeats().add(seat);
return car;
}
}
pom.xml:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>javaeecourse</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>Java EE Course App</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>8.0.19</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.10.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.4.10.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
<build>
<finalName>javaeecourse</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<groupId>org.apache.tomee.maven</groupId>
<artifactId>tomee-embedded-maven-plugin</artifactId>
<version>8.0.1</version>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
I will be grateful for any help.
Thanks to the hint provided by #areus in the question comment, I was able to resolve the case. I am posting an answer here if anyone had a similar issue in the future.
There was 1 major issue and 1 "bad practice" issue.
The main problem was that I was using a JTA transaction type and referenced the jta-data-source by JNDI name, but the resources.xml was located under webapp instead of resources/META-INF.
After I moved the resource.xml to the META-INF, the database could be properly created and entities were persisted.
Additionally, in my configuration, I have used a deprecated JDBC Driver for MySQL 8. According to this doc, since MySQL 8.0, the driver is now com.mysql.cj.jdbc.Driver, not com.mysql.jdbc.Driver.
I also removed the unnecessary properties, so the config is now quite clear and everything works fine.
resources/META-INF/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" version="2.2"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<persistence-unit name="my-persistence-unit" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>jdbc/javaeecourse</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="tomee.jpa.factory.lazy" value="true"/>
</properties>
</persistence-unit>
</persistence>
resources/META-INF/resources.xml
<?xml version="1.0" encoding="UTF-8"?>
<tomee>
<Resource id="jdbc/javaeecourse" type="javax.sql.DataSource">
JdbcDriver = com.mysql.cj.jdbc.Driver
JdbcUrl = jdbc:mysql://localhost:3306/javaeecourse?serverTimezone=UTC
UserName = root
Password = admin
jtaManaged = true
</Resource>
</tomee>
Here is also a great article regarding the JTA/RESOURCE_LOCAL transaction types as well as jta-data-source and non-jta-data-source configuration, which helped me understand the details.
Related
I'm following the Spring training guide „Build a restful web service“ The application throws an error when I try and access http://localhost:8080/greeting. The error is:
ERROR 17903 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags = ] with root cause
Working on Ubuntu 20.04, openjdk version "11.0.14.1" 2022-02-08,
mvn -version:
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Java version: 1.8.0_312, vendor: Private Build, runtime: /usr/lib/jvm/java-8-openjdk-amd64/jre
Here are the relevant classes:
public class GreetingController {
private static final String template = "Hello, % s!";
private final AtomicLong counter = new AtomicLong();
public Greeting greeting(#RequestParam(value = "name",
defaultValue = "World") String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
}
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
pom.xml
<?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.6.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I used Spring Initializr and added the dependency Spring Web as in the guide. Also the line:
com.example.demo.DemoApplication : Starting DemoApplication using Java 17.0.1
Seems like it is expecting Java 17 to run it. I have used Java 11 and Maven 2.6.7 in initializr and java 11 is set on my local machine.
Thanks in advance for any help
DataSperling
Solution: In the class:
public class GreetingController
The line:
private static final String template = "Hello, % s!";
Should read:
private static final String template = "Hello, %s!";
Also the url neads to be:
http://localhost:8080/greeting
NOT
https://localhost:8080/greeting
SSL is not required.
Using a Connection Pool
I am using a Hikari Connection Pool to interact with the MySQl database backend in a Java based Web project. I decided to upgrade the library versions to their most recent stable versions and now I cannot connect to the database anymore.
Java 8
MySQL 5.7
Tomcat 8
Dependencies
I use the following Maven dependencies:
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.4.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-hikaricp</artifactId>
<version>5.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-envers</artifactId>
<version>5.2.0.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.2</version>
</dependency>
Hibernate
The project compiles fine, no libraries are missing. This is my hibernate configuration file:
<session-factory>
<property name="hibernate.connection.provider_class">com.zaxxer.hikari.hibernate.HikariConnectionProvider</property>
<property name="hibernate.hikari.dataSourceClassName">com.mysql.jdbc.jdbc2.optional.MysqlDataSource</property>
<property name="hibernate.hikari.dataSource.url">jdbc:mysql://localhost:3306/CitationUserDB?useSSL=false</property>
<property name="hibernate.hikari.dataSource.user">dbUser</property>
<property name="hibernate.hikari.dataSource.password">vErYsEcReT</property>
<property name="hibernate.hikari.dataSource.cachePrepStmts">true</property>
<property name="hibernate.hikari.dataSource.prepStmtCacheSize">250</property>
<property name="hibernate.hikari.dataSource.prepStmtCacheSqlLimit">2048</property>
<property name="hibernate.hikari.dataSource.useServerPrepStmts">true</property>
<mapping class="Database.Authentication.User"/>
</session-factory>
SessionFactory
I use this Hibernate Util class to get the session object.
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
/**
* Hibernate session management
*/
public class HibernateUtilUserAuthentication {
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
// loads configuration and mappings
Configuration configuration = new Configuration().configure("hibernate.userauthentication.cfg.xml");
ServiceRegistry serviceRegistry
= new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
// builds a session factory from the service registry
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
}
return sessionFactory;
}
}
Error
The following error is thrown, when the first database access happens in the source code. There seems to be a problem with the claspath, but all required libraries are there and I can see them in IntelliJ.
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:244)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:208)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:51)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:217)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.handleTypes(MetadataBuildingProcess.java:352)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:111)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:691)
at Database.Authentication.HibernateUtilUserAuthentication.getSessionFactory(HibernateUtilUserAuthentication.java:104)
at Database.Authentication.UserAPI.authenticateUser(UserAPI.java:133)
at Database.Authentication.UserAuthentication.login(UserAuthentication.java:60)
at Bean.LoginBean.login(LoginBean.java:94)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.el.parser.AstValue.invoke(AstValue.java:247)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:267)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
... 32 more
Caused by: org.hibernate.HibernateException: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.mysql.jdbc.jdbc2.optional.MysqlDataSource
at com.zaxxer.hikari.hibernate.HikariConnectionProvider.configure(HikariConnectionProvider.java:86)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:217)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
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:88)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:234)
... 56 more
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.mysql.jdbc.jdbc2.optional.MysqlDataSource
at com.zaxxer.hikari.util.UtilityElf.createInstance(UtilityElf.java:120)
at com.zaxxer.hikari.pool.PoolUtilities.initializeDataSource(PoolUtilities.java:110)
at com.zaxxer.hikari.pool.BaseHikariPool.<init>(BaseHikariPool.java:157)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:60)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:48)
at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:80)
at com.zaxxer.hikari.hibernate.HikariConnectionProvider.configure(HikariConnectionProvider.java:82)
... 64 more
Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.jdbc2.optional.MysqlDataSource
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1305)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1139)
at com.zaxxer.hikari.util.UtilityElf.createInstance(UtilityElf.java:105)
... 70 more
But the library is there:
It is copied to Tomcat during deployment:
./webapps/Testapplication/WEB-INF/lib/mysql-connector-java-6.0.2.jar
I have no idea why the JDBC MySQL driver cannot be found. Any help is really appreciated.
Thank you in advance!
The package structure has changed in mysql-connector-java-6. Switch to mysql-connector-java-5.x
<!-- http://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
The database table is NOT auto-created by the <property name="hbm2ddl.auto">update</property> settings in hibernate-cfg.xml, with the following combination:
Java 8 + Tomcat 8 + MySQL + Hibernate 5
Java version:
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
MySQL version:
mysql Ver 14.14 Distrib 5.6.16, for osx10.7 (x86_64) using EditLine wrapper
Tomcat version:
apache-tomcat-8.0.22
pom.xml snippets:
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.0.3.Final</version>
</dependency>
Entity class:
package com.test.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;
#Entity
#Table( name = "EVENTS" )
public class Event {
#Id
#GeneratedValue(generator="increment")
#GenericGenerator(name="increment", strategy = "increment")
private Long id;
private String title;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "EVENT_DATE")
private Date date;
public Event() {}
public Long getId() { return id; }
private void setId(Long id) { this.id = id; }
public Date getDate() { return date; }
public void setDate(Date date) { this.date = date; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
}
Hibernate SessionFactory initialization:
String resource = "hibernate.cfg.xml";
Configuration configuration = new Configuration();
configuration.configure(resource);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
SessionFactory sessionFactoryCore = configuration.buildSessionFactory(serviceRegistry);
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.username">mysqluser</property>
<property name="connection.password">******</property>
<property name="hbm2ddl.auto">update</property>
<property name="hibernate.max_fetch_depth">3</property>
<mapping class="com.test.entity.Event" />
</session-factory>
</hibernate-configuration>
HOWEVER, the table was created into MySQL database, with the following combination:
Java 8 + Tomcat 8 + MySQL + Hibernate 4
Everything same as above, except in pom.xml, I was using hibernate 4 instead of 5:
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.11.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.11.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>4.3.11.Final</version>
</dependency>
What am I missing in Hibernate 5?
We faced a similar problem after upgrading to Hibernate 5.x and this was solved by changing the dialect to org.hibernate.dialect.MySQL5Dialect.
add <property name="javax.persistence.schema-generation.database.action">create</property> in your hibernate config file.
try something like that in sessionFactoryInitialisation :
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().configure(configFile).build();
Metadata metadata =new MetadataSources(standardRegistry).getMetadataBuilder().build();
sessionFactory = metadata.getSessionFactoryBuilder().build();
return sessionFactory;
I am using #ResponseBody to return Json object in Spring MVC. It works as expected on release 4.0.7 and 3.2.11, but it returns HTTP status 406 when I try to use the latest Spring release 4.1.1(as of 10/16) with no any other configuration changes. Is this considered a bug or the 4.1.1 requires different configuration?
the latest jackson jar is already in the classpath
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
The example on the Spring document works fine
#RequestMapping(value = "/something", method = RequestMethod.PUT)
#ResponseBody
public String helloWorld() {
return "Hello World";
}
when the return type is String. The problem happens when the return type is a POJO.
Maven pom.xml:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.3</version>
</dependency>
and spring mvc config file (eg:spring-mvc.xml)
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
Got it working after removing Jackson 1.* replacing with the 2.4.4 (JAXRS), which will import all the other dependencies, jackson-core, jackson-databind and jackson-annotations.
Removed
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
Added
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId>
<version>2.4.4</version>
</dependency>
http://www.codingpedia.org/ama/jquery-ui-autocomplete-not-working-in-spring-4-1/
and in the servlet xml
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="favorParameter" value="true" />
<property name="mediaTypes" >
<value>
json=application/json
xml=application/xml
</value>
</property>
</bean>
if the jackson annotate is imported in the class files, it should also be replaced
Removed
import org.codehaus.jackson.annotate.JsonIgnoreProperties
Added
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
I was struggling with similar issue migrating from 3.2 to spring 4.2.
Was getting
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: No converter found for return value of type:
posting it here so people can find it by exception name :) It took me half a day to find this article. Thanks #Vito and #Aias
Combination of both previous answers work as well, if you do not want register custom contentNegotiationManager you can do following:
remove all jackson dependencies from
pom.xml
and use latest one
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId>
<version>2.6.1</version>
</dependency>
servlet.xml
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
Am using Jersey 1.15, JDK 1.6, Tomcat 7, Maven 2.2.1 to create a simple Restful Web Service that should return a JSON String from a POJO that I mapped.
Here's my pojo:
package com.myservice.domain;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Person {
private String firstName;
private String lastName;
// Getters & Setters
}
my webservice:
package com.myservice.resource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.myservice.domain.Person;
#Path("/service")
public class MyService {
#GET
#Path("showPerson")
#Produces(MediaType.APPLICATION_JSON)
public Person getPerson() {
Person person = new Person();
person.setFirstName("John");
person.setLastName("Doe");
return person;
}
}
Here's my 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.myservice</groupId>
<artifactId>myservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>My Web Service</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.15</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.9</version>
</dependency>
</dependencies>
<build>
<finalName>myservice</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
My web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
metadata-complete="true">
<display-name>My Web Service</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.myservice.resource</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
After deploying to tomcat, when I try to invoke the web service like this:
curl -X GET http://localhost:8080/myservice/rest/service/showPerson
I get the following error:
Nov 20, 2012 10:40:06 AM com.sun.jersey.spi.container.ContainerResponse write
SEVERE: A message body writer for Java class com.myservice.domain.Person,
and Java type class com.myservice.domain.Person,
and MIME media type application/json was not found
Nov 20, 2012 10:40:06 AM com.sun.jersey.spi.container.ContainerResponse write
SEVERE: A message body writer for Java class com.myservice.domain.Person,
and Java type class com.myservice.domain.Person, and MIME media type
application/json was not found
Nov 20, 2012 10:40:06 AM com.sun.jersey.spi.container.ContainerResponse write
SEVERE: The registered message body writers compatible with the
MIME media type are: */* ->
com.sun.jersey.core.impl.provider.entity.FormProvider
com.sun.jersey.core.impl.provider.entity.StringProvider
com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
com.sun.jersey.core.impl.provider.entity.FileProvider
com.sun.jersey.core.impl.provider.entity.InputStreamProvider
com.sun.jersey.core.impl.provider.entity.DataSourceProvider
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.ReaderProvider
com.sun.jersey.core.impl.provider.entity.DocumentProvider
com.sun.jersey.core.impl.provider.entity.StreamingOutputProviderfg
com.sun.jersey.core.impl.provider.entity.SourceProvider$SourceWriter
com.sun.jersey.server.impl.template.ViewableMessageBodyWriter
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
Nov 20, 2012 10:40:06 AM com.sun.jersey.spi.container.ContainerResponse
write
SEVERE: The registered message body writers compatible with the
MIME media type are:
*/* ->
com.sun.jersey.core.impl.provider.entity.FormProvider
com.sun.jersey.core.impl.provider.entity.StringProvider
com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
com.sun.jersey.core.impl.provider.entity.FileProvider
com.sun.jersey.core.impl.provider.entity.InputStreamProvider
com.sun.jersey.core.impl.provider.entity.DataSourceProvider
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.ReaderProvider
com.sun.jersey.core.impl.provider.entity.DocumentProvider
com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider
com.sun.jersey.core.impl.provider.entity.SourceProvider$SourceWriter
com.sun.jersey.server.impl.template.ViewableMessageBodyWriter
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
SEVERE: Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException:
com.sun.jersey.api.MessageException:
A message body writer for Java class
com.myservice.domain.Person,
and Java type class com.myservice.domain.Person,
and MIME media type application/json was not found
com.sun.jersey.api.MessageException:
A message body writer for Java class com.myservice.domain.Person,
and Java type class com.myservice.domain.Person, and MIME media type
application/json was not found
HTTP Status 500 - Internal Server Error
The server encountered an internal error that prevented it from
fulfilling this request.
After scouring the Internet, I tried inserting the following proposed solution that everyone suggested into web.xml:
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
But it still gives me the same issue! It does return the correct data marshalled to XML if I use APPLICATION_XML, however.
Would really appreciate it if someone could point me in the right direction.
Thank you very much for taking the time to read this.
Add Genson library in your dependencies.
It will automatically enable JSON-POJO databinding.
Add jersey-json to your dependencies. It will add a JSON serialization implementation.
Add this to pom.xml
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.8</version>
</dependency>