I have created Spring integration test in my application.
The problem is, one test doesn't rollback properly, leaves some stuff in database and causes subsequent tests to fail.
I have noticed, that tests works good if persisted entity is simple entity.
The test fails, when entity is part of inheritance hierarchy and inheritance type is of type InheritanceType.JOINED.
When I change it to InheritanceType.SINGLE_TABLE it desn't fail.
Below is the code:
Test class:
#RunWith(SpringJUnit4ClassRunner.class)
#Transactional
#ContextConfiguration(locations = {"classpath:beans/repository-beans.xml"})
public class OnlyParentRollbackProblemSpringTest {
#PersistenceContext
private EntityManager entityManager;
#Test
//PASSES
public void isDBEmptyTest_1() throws Exception {
Query countQuery = entityManager.createQuery("select count(qi) from " + ParentEntity.class.getSimpleName() + " qi");
int elementsCount = ((Long)countQuery.getSingleResult()).intValue();
assertThat(elementsCount).isEqualTo(0);
}
#Test
//PASSES
public void testThatInfluencesOtherTests() {
ParentEntity queueItem = new ParentEntity();
entityManager.persist(queueItem);
ParentEntity queueItem1 = new ParentEntity();
entityManager.persist(queueItem1);
// given
flush();
// when
Query deleteQuery = entityManager.createQuery("delete from " + ParentEntity.class.getSimpleName());
deleteQuery.executeUpdate();
flush();
// then
Query countQuery = entityManager.createQuery("select count(qi) from " + ParentEntity.class.getSimpleName() + " qi");
int elementsCount = ((Long)countQuery.getSingleResult()).intValue();
assertThat(elementsCount).isEqualTo(0);
}
#Test
//FAILS
public void isDBEmptyTest_2() throws Exception {
Query countQuery = entityManager.createQuery("select count(qi) from " + ParentEntity.class.getSimpleName() + " qi");
int elementsCount = ((Long)countQuery.getSingleResult()).intValue();
assertThat(elementsCount).isEqualTo(0);
}
private void flush() {
entityManager.flush();
entityManager.clear();
}
}
spring configuration:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="no.mintra.offlinetrainingportal.infrastructure.persistence" />
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="H2DataSource" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="dataSource" ref="H2DataSource" />
<property name="jpaVendorAdapter" ref="H2JpaVendorAdaptor" />
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.hbm2ddl.auto" value="create-drop" />
</map>
</property>
</bean>
<bean id="H2DataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;MODE=MYSQL;LOCK_MODE=3"/>
</bean>
<bean id="H2JpaVendorAdaptor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" />
</bean>
Entities:
#javax.persistence.Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class ParentEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
public ParentEntity() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
#Entity
public class SecondChildEntity extends ParentEntity {
#Column(unique = true)
#NotNull
private Integer userId;
public SecondChildEntity(Integer userId) {
this.userId = userId;
}
public Integer getUserId() {
return userId;
}
}
And pom.xml file:
<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>test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>test</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>4.8.1</junit.version>
<org.springframework.version>3.1.0.RELEASE</org.springframework.version>
<log4j.version>1.2.15</log4j.version>
<org.slf4j.version>1.5.8</org.slf4j.version>
<hibernate-core.version>3.6.8.Final</hibernate-core.version>
<hibernate-validator.version>4.1.0.Final</hibernate-validator.version>
<commons-dbcp.version>1.2.2</commons-dbcp.version>
<h2database.version>1.3.163</h2database.version>
<commons-collections.version>3.2.1</commons-collections.version>
<javax.servlet.version>2.5</javax.servlet.version>
<javax.validation.version>1.0.0.GA</javax.validation.version>
<fest.version>1.2</fest.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2database.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert</artifactId>
<version>${fest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
<exclusions>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<exclusions>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>ejb3-persistence</artifactId>
</exclusion>
</exclusions>
<version>${hibernate-core.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate-core.version}</version>
</dependency>
</dependencies>
This issue is specific to H2 DBMS.
H2Dialect contains the following warning:
if ( !( majorVersion > 1 || minorVersion > 2 || buildId >= 139 ) ) {
log.warn(
"The {} version of H2 implements temporary table creation such that it commits " +
"current transaction; multi-table, bulk hql/jpaql will not work properly",
( majorVersion + "." + minorVersion + "." + buildId )
);
}
You face this issue because executing bulk delete against entity with JOINED inheritance involves creation of temporary table (see generated SQL), so that the first part of transaction gets committed.
As a workaround you can use native SQL queries instead of bulk HQL delete query. Or just use another in-memory database such as HSQLDB.
Related
I am building a spring MVC webapp.I am using JPA Hibernate and MySQL.Hibernate generate table successfully(if i am not wrong) but can not displayed or created on MySQL.I install MySQL Server Community 8.0.20.After finished installed successfully,I checked services on Windows 10 and there are two server installed.MySQL and MySQL80.MySQL80 installed and work fine.I change Image Path of MySQL instance(Just a test if app should run with MySQL server instance and problem was there) and put the same path that exist in MySQL80 and it works succesfully also with MySQL server.They have the same image path and logically will work but just give it a try.
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" 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">
<persistence-unit name="elearningPU">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="hibernate.search.default.optimizer.operation_limit.max" value="1000" />
<property name="hibernate.search.default.optimizer.transaction_limit.max" value="100" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.cj.jdbc.Driver" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="pasw1" />
<!-- shtim -->
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/elearningdb" />
<property name="hibernate.max_fetch_depth" value="3" />
<!-- You may want to change this to false in production -->
<property name="hibernate.show_sql" value="true" />
<!-- You can change this to create at the first time -->
<property name="hibernate.hbm2ddl.auto" value="create" />
<!-- Set this to 0 otherwise you sometimes get errors -->
<property name="hibernate.connection.pool_size" value="0" />
<!-- <property name="packagesToScan" value="com.elearning.domain" /> -->
</properties>
</persistence-unit>
</persistence>
spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="elearningPU" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<context:component-scan base-package="com.elearning.controller,com.elearning.domain" />
<context:annotation-config/>
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver" />
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles.xml</value>
</list>
</property>
</bean>
</beans>
TestTable.java
package com.elearning.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="first_table")
public class TestTable implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private long id;
private String name;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
#Column(name="test_name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "TestTable [id=" + id + ", name=" + name + "]";
}
}
Eclipse Console
MySQL Workbench
Services
Registry Editor
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>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<groupId>com.elearning</groupId>
<artifactId>com.elearning.webapp</artifactId>
<name>E-Learning</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>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<spring.version>5.2.6.RELEASE</spring.version>
<tiles.version>3.0.8</tiles.version>
<hibernate.version>5.4.15.Final</hibernate.version>
</properties>
<repositories>
<repository>
<id>Maven Central</id>
<url>https://repo.maven.apache.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<!-- JEE MOVED FROM ORACLE TO JAKARTA EE -->
<!-- <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId>
<version>2.5</version> </dependency> -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>4.0.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Tiles -->
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>${tiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-api</artifactId>
<version>${tiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>${tiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-servlet</artifactId>
<version>${tiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-el</artifactId>
<version>${tiles.version}</version>
</dependency>
<!-- Spring MVC Framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.2.7.RELEASE</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.2.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>javax.activation</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.30</version>
</dependency>
<!-- Commons -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-configuration2</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-digester3</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>com.elearning.webapp</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven
defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</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>
On persistence.xml JPA Content,i changed:
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
to
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
and table created succesfully on MySQL now.
I'm a bit newbie and I've been trying to link my Hibernate code to database for some days, without success. This is the error I'm getting:
Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named TestMySqlHibernate
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:85)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at testDummyEntrance.DummyInterface.main(DummyInterface.java:17)
The persistence.xml file
<persistence-unit name="TestMySqlHibernate">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="javax.persistence.jdbc.driver"
value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/testalan" />
<property name="javax.persistence.jdbc.user" value="alan" />
<property name="javax.persistence.jdbc.password"
value="password" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
The dummy function:
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("TestMySqlHibernate");
EntityManager em=entityManagerFactory.createEntityManager();
em.close();
System.out.println("Done");
}
I've also checked that the persistence.xml file is correctly located under src/main/resources/META-INF, and is included in build path.
I'm probably doing something terribly stupid, but I can't figure out what this could be. I've checked out about 10 possibilities and still the same. If it helps, I can connect with Data Source Explorer, and tried both Oracle and MySql.
Using last version of MySql, and driver 8.0.11, all in local, in same machine.
I can post POM.xml or any other data if it helps.
Thanks in advance.
EDIT:
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.javavids.hibernate.tests</groupId>
<artifactId>testHibernateMaven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.3.1.Final</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.2.Final</version>
</dependency>
<dependency>
<groupId>javax.ejb</groupId>
<artifactId>ejb-api</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.hibernate.common</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-bom</artifactId>
<version>3.1.3</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.4.0.Final</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.18.3</version>
</dependency>
<dependency>
<groupId>org.jboss.bom</groupId>
<artifactId>jboss-javaee-6.0-with-hibernate</artifactId>
<version>1.0.7.Final</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jboss.bom</groupId>
<artifactId>jboss-javaee-6.0-with-tools</artifactId>
<version>1.0.7.Final</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jboss.bom</groupId>
<artifactId>
jboss-javaee-6.0-with-transactions
</artifactId>
<version>1.0.7.Final</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jboss.bom</groupId>
<artifactId>jboss-javaee-6.0-with-logging</artifactId>
<version>1.0.7.Final</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>20040616</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>20030211.134440</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jboss-modules</artifactId>
<version>4.0.0.Beta3</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.7</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
</dependencies>
</dependencyManagement>
Thanks to the help of #SimonMartinelli, I found it. Also, #K.Nicholas suggestion is correct, the resource type is not JTA and has to be clarified. Kudos to them.
The resulting persistence.xml looks like this:
<persistence-unit name="TestMySqlHibernate" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="javax.persistence.jdbc.driver"
value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/testalan?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC"/>
<property name="javax.persistence.jdbc.user" value="alan" />
<property name="javax.persistence.jdbc.password"
value="password" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
Please note their changes (remove provider tag and add transaction-type property) and the UTC addition that I had to do using MySQL.
Not sure if has something to do with the driver version or what, but the provider tag is a runtime-breaker with driver 8.0.11.
Thanks both for the solution guys, you solved my headache!
EDIT: As newbie... how can I vote your answers as positive?
I am trying to create my own eshop. I have problem on the creation of beans.
My packages are the following:
Controller
package com.emusicstore.controller;
import java.io.IOException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import com.emusicstore.dao.ProductDao;
import com.emusicstore.model.Product;
#Controller
public class HomeController {
#Autowired
private ProductDao productDao;
#RequestMapping("/")
public String home(){
return "home";
}
#RequestMapping("/productList")
public String getProducts(Model model) {
List<Product> products = productDao.getAllProducts();
model.addAttribute("products", products);
return "productList";
}
ProductDao
package com.emusicstore.dao;
import java.util.List;
import com.emusicstore.model.Product;
public interface ProductDao
{
void addProduct(Product product);
Product getProductById (String id);
List<Product> getAllProducts();
void deleteProduct (String id);
}
ProductDaoImpl
package com.emusicstore.impl;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.emusicstore.dao.ProductDao;
import com.emusicstore.model.Product;
#Component
#Transactional
public class ProductDaoImpl implements ProductDao {
#Autowired
private SessionFactory sessionFactory;
public void addProduct(Product product) {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(product);
session.flush();
}
public Product getProductById(String id) {
Session session = sessionFactory.getCurrentSession();
Product product = (Product) session.get(Product.class, id);
session.flush();
return product;
}
public List<Product> getAllProducts() {
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("from Product");
List<Product> products = query.list();
session.flush();
return products;
}
public void deleteProduct(String id) {
Session session = sessionFactory.getCurrentSession();
session.delete(getProductById(id));
session.flush();
}
}
Product
package com.emusicstore.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private String productId;
private String productName;
private String productCategory;
private String productDescription;
private double productPrice;
private String productCondition;
private String productStatus;
private int unitInStock;
private String productManufacture;
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductCategory() {
return productCategory;
}
public void setProductCategory(String productCategory) {
this.productCategory = productCategory;
}
public String getProductDescription() {
return productDescription;
}
public void setProductDescription(String productDescription) {
this.productDescription = productDescription;
}
public double getProductPrice() {
return productPrice;
}
public void setProductPrice(double productPrice) {
this.productPrice = productPrice;
}
public String getProductCondition() {
return productCondition;
}
public void setProductCondition(String productCondition) {
this.productCondition = productCondition;
}
public String getProductStatus() {
return productStatus;
}
public void setProductStatus(String productStatus) {
this.productStatus = productStatus;
}
public int getUnitInStock() {
return unitInStock;
}
public void setUnitInStock(int unitInStock) {
this.unitInStock = unitInStock;
}
public String getProductManufacture() {
return productManufacture;
}
public void setProductManufacture(String productManufacture) {
this.productManufacture = productManufacture;
}
}
Also I have a jdbc.properties file with info about username, password etc to connect wit MySQL.
I think that the above files are correct.
applicationContext.xml (part of my code)
<beans profile="dev">
<context:property-placeholder location="jdbc.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="username" value="${jdbc.username}"></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.emusicstore.*</value>
</list>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- Is <tx:annotation-driven /> is necessary in this file?? -->
</beans>
dispatcher-servlet.xml (part of my code)
<context:annotation-config></context:annotation-config>
<context:annotation-config />
<mvc:annotation-driven />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" />
<tx:annotation-driven />
web.xml (part of my code)
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/dispatcher-servlet.xml
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
When I try to run my project all the errors associated with:
org.springframework.beans.factory.BeanCreationException
org.springframework.beans.factory.NoSuchBeanCreationDefinitionException
The first error is on the creation of bean 'homeController'.
Could not autowire field: private com.emusicstore.dao.ProductDao com.emusicstore.controller.HomeController.productDao;
My questions.
1) applicationContext.xml
On the which file (or files) I have to put? Is the existing path right or I have to modify it specifically (e.g com.emusicstore.dao)? At this list, I have to put the whole path for my dao, model ?
2) dispatcher-servlet.xml
Same question for the right path of context:component-scan. On the base-package may I specify the package only to my controller (com.emusicstore.controller)?
I searched to older posts but I do not solve my problem.
Thank you in advance, Mike
EDIT
Summary of (our) changes
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<beans profile="dev">
<context:annotation-config></context:annotation-config>
<context:component-scan base-package="com.emusicstore.dao, com.emusicstore.impl"></context:component-scan>
<context:property-placeholder location="jdbc.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="username" value="${jdbc.username}"></property>
</bean>
<!-- MY CHANGES -->
<!-- LocalSessionFactoryBean for hibernate4 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<!-- CHANGE HERE FOR MySQL -->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<!-- To know where is ProductDao -->
<property name="packagesToScan">
<list>
<value>com.emusicstore.dao</value>
<value>com.emusicstore.impl</value>
</list>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
</beans>
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<context:component-scan base-package="com.emusicstore." />
<context:annotation-config></context:annotation-config>
<mvc:annotation-driven />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" />
<tx:annotation-driven />
</beans>
Web.xml Exactly the same code as you wrote
The same errors continues to exist but the "homepage" on Eclipse has changed to this
HTTP Status 500 - Servlet.init() for servlet dispatcher threw exception
type Exception report
message Servlet.init() for servlet dispatcher threw exception
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Servlet.init() for servlet dispatcher threw exception
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:495)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:767)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1347)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Unknown Source)
And then the previous errors again...
EDIT
web.xml (first lines)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
pom.xml (all my file)
<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.mywebsite</groupId>
<artifactId>eMusicStore</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<!-- To work with Hibernate -->
<!-- All Hibernate in single dependency -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.0.2.Final</version>
</dependency>
<!-- MySql -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- To connect with the jdbc.properties file -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Traditionnaly we have 2 contexts in a Spring MVC application. The root context (here your applicationContext.xml) where we define all beans not dedicated to web stuff like DAO, Securtity, etc... And the DispatcherServlet context (dispatcher-servlet.xml) where we define all beans related to web operations like controllers.
So, put your DAO bean in applicationContext.xml like this : <context:component-scan base-package="com.emusicstore.dao"/> and your transaction manager <tx:annotation-driven transaction-manager="transactionManager"/>
For your 2nd question, you can just put the super package like this : <context:component-scan base-package="com.emusicstore."/>
EDIT
Here how your web.xml should look like :
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/dispatcher-servlet.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
I your configuration you mixed the 2 contexts.
I am new in spring boot. I want to configure spring boot with mysql, hibernate, jpa and jsp. When i want to start it i gen an error: "Error creating bean with name 'sessionFactory' etc.", more in stacktrace:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [com/budget/configs/DatabaseConfig.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Class name must not be null
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:732) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861) ~[spring-context-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) ~[spring-context-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
at com.budget.HomeBudgetApplication.main(HomeBudgetApplication.java:15) [classes/:na]
Caused by: java.lang.IllegalArgumentException: Class name must not be null
at org.springframework.util.Assert.notNull(Assert.java:115) ~[spring-core-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.util.ClassUtils.convertClassNameToResourcePath(ClassUtils.java:960) ~[spring-core-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.scanPackages(LocalSessionFactoryBuilder.java:282) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:434) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
... 16 common frames omitted
pom.xml `4.0.0
<groupId>com.budget</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>homeBudget</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.javax.persistence/hibernate-jpa-2.1-api -->
<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-validator</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<packaging>war</packaging>
`
HomeBudgetApplication.java
#Configuration
#EnableAutoConfiguration()
#ComponentScan({"com.budget.*"})
public class HomeBudgetApplication {
public static void main(String[] args) {
SpringApplication.run(HomeBudgetApplication.class, args);
}
}
DatabaseConfig.java
#Configuration
#ComponentScan("com.budget.*")
#EnableWebMvc
#EnableTransactionManagement
#PropertySource("classpath:application.properties")
public class DatabaseConfig extends WebMvcConfigurerAdapter {
#Autowired
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("spring.datasource.driverClassName"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(env.getProperty("com.budget.*"));
sessionFactoryBean.setHibernateProperties(hibProperties());
return sessionFactoryBean;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put("spring.jpa.database-platform", env.getProperty("spring.jpa.database-platform"));
properties.put("spring.jpa.hibernate.ddl-auto", env.getProperty("spring.jpa.hibernate.ddl-auto"));
properties.put("spring.jpa.show-sql", env.getProperty("spring.jpa.show-sql"));
return properties;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
}
application.properties
'spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/budget
spring.datasource.username=marcin
spring.datasource.password=marcin123
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
entitymanager.packages.to.scan=com.budget'
First use the framework and not work around the framework. You also state you want to use Spring Boot and JPA but your configuraiton shows you are trying very hard not to use Spring Boot and that you don't use JPA but plain hibernate.
First remove your DatabaseConfig. (Yes remove it).
Move your HomeBudgetApplication to com.bugdet and remove all annotations and replace with a simple #SpringBootApplication.
#SpringBootApplication
public class HomeBudgetApplication {
public static void main(String[] args) {
SpringApplication.run(HomeBudgetApplication.class, args);
}
}
In your application.properties add spring.mvc.view properties to have the InternalResourceViewResolver automatically configured. ALso remove the entitymanager.packages.to.scan as that is added for you already.
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/budget
spring.datasource.username=marcin
spring.datasource.password=marcin123
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
Everything else will be configured by Spring Boot. It will detect your web, jpa and transactions and will automatically configure it.
If you have any repository etc. based on SessionFactory replace it to work on the EntityManager instead.
You scan the packages twice on HomeBudgetApplication and DatabasebaseConfig.
Delete componenet scan on DatabasebaseConfig.
Good luck
<beans:bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="${jdbc.driverClassName}" />
<beans:property name="url" value="${jdbc.databaseurl}" />
<beans:property name="username" value="${jdbc.username}" />
<beans:property name="password" value="${jdbc.password}" />
</beans:bean>
<beans:bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="packagesToScan" value="com.kdkce.erp.entity" />
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.format.sql">true</beans:prop>
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<properties>
<java-version>1.8</java-version>
<org.springframework-version>4.2.2.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
<hibernate-version>5.0.2.Final</hibernate-version>
<spring-security-version>3.2.8.RELEASE</spring-security-version>
<mysql-version>5.1.9</mysql-version>
</properties>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-version}</version>
</dependency>
<!-- new dependency added for spring jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate-version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.8</version>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring-security-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring-security-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring-security-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring-security-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.1</version>
</dependency>
I've gone through absolutely every single post here related to the subject, trying all suggested here options... and after a couple of days, it still doesn't work for me.
In short, what I want to do is:
Send data from html form to the Spring MVC controller using jquery and $.post function with JSON type.
On the controller side I have a method which should return an object with one file of String type.
1st point works properly, I manage to send a POST request and receive it properly on the controller side. What doesn't work is the answer from controller back to jsp and the function defined for $.post(). I debugged it on web browser side and I can see that the Content-Type of response is not "application/json" (hence the Error 406, I believe).
Here's what I've got:
JSP:
<%# taglib uri="http://www.springframework.org/tags/form"
prefix="springForm"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<link rel="stylesheet"
href="//code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css"/>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.3/jquery-ui.js"></script>
</head>
<body>
<springForm:form method="POST" commandName="signInDto"
action="/EquipmentManager/signIn.do" id="add-user-form">
<p>
Login:
<springForm:input path="login" />
<springForm:errors path="login" cssClass="error" />
</p>
<p>
Password:
<springForm:password path="password" />
<springForm:errors path="password" cssClass="error" />
</p>
<p>${errorMessage}
<p />
<input type="submit" value="Sign In" />
</springForm:form>
<script type="text/javascript">
function collectFormData(fields) {
var data = {};
for (var i = 0; i < fields.length; i++) {
var $item = $(fields[i]);
data[$item.attr('name')] = $item.val();
}
return data;
}
$(document).ready(
function() {
var $form = $('#add-user-form');
$form.bind('submit', function(e) {
// Ajax validation
var $inputs = $form.find('input');
var data = collectFormData($inputs);
$.post('/EquipmentManager/signInValidate', data,
function(response) {
$form.find('.control-group').removeClass(
'error');
$form.find('.help-inline').empty();
$form.find('.alert').remove();
if (response.value == 'FAIL') {
alarm(response.value);
} else {
$form.unbind('submit');
$form.submit();
}
}, 'json');
e.preventDefault();
return false;
});
});
</script>
</body>
</html>
Controller:
#RequestMapping(value = "/signInValidate", method = RequestMethod.POST)
public #ResponseBody TestObject signInValidate(#Valid SignInDto signInDto,
BindingResult bindingResult) {
TestObject testObject = new TestObject();
if (bindingResult.hasErrors()) {
testObject.setValue("FAIL");
logger.info("FAIL");
} else {
testObject.setValue("SUCCESS");
logger.info("SUCCESS");
}
return testObject;
}
Bean:
public class TestObject {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Dispatcher Servlet:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.equipment.controller" />
<mvc:annotation-driven />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/view/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.esocphotoclub</groupId>
<artifactId>EquipmentManager</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>EquipmentManager Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.8.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.3.Final</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.11</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
<build>
<finalName>EquipmentManager</finalName>
</build>
</project>
I've already tried different versions of jackson-*, explicit defining of ContentNegotiatingViewResolver, explicit specification of produces="application/json" in #RequestMapping, TestObject serialisation, and few other things I've found here. None of them work for me.
To give you as much info as possible, all works fine if I don't request 'json' type in $.post and in the controller I return a simple string. That's not what I want to do though. What I want is to submit a request for validation purpose and receive an object, not a simple string.
Any hint I'll very much appreciate, perhaps there's something I still haven't try.
Many thanks in advance!
I hope you have all jackson mapping and if that is the case you are missing jsonview. Can you try the below. All we are doing is setting multiple view resolvers.
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/view/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="jsonViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="order" value="1"/>
<property name="location" value="/WEB-INF/views.xml"/>
</bean>
Create a file called views.xml in you WEB-INF folder and add the below entry.
<bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView"/>
It took me a few days, but I finally managed to sort this out by trial and error method.
What I did was simply add another jackson dependency in the POM file: jackson-databind and now it works just fine.