I have a mobile application which connects to Azure web services written in Spring Hibernate which communicates to Azure SQL server for performing data operations.
In hibernate we dont have any connection manager configured. We are using Hibernate sessionFactory for managing the connections.
Recently after too many users using the app, we found that the Azure automatically restarting the services after reaching the max connection limits of Azure which is 1920 TCP connections.
TCP connections once used either go into CLOSE_WAIT state or TIME_WAIT state.
They are not properly closing the connections.
Is this related to some Azure VM Server not closing the connections or has to do with the Java coding style used.
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.mastek</groupId>
<artifactId>transaction-rs</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>transaction-rs</name>
<properties>
<springframework.version>4.0.6.RELEASE</springframework.version>
<hibernate.version>4.3.6.Final</hibernate.version>
<sqlserver.version>4.0</sqlserver.version>
<swagger-version>1.3.0</swagger-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- MS SQL server driver -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>${sqlserver.version}</version>
</dependency>
<!-- orika mapper -->
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>1.4.6</version>
</dependency>
<!-- resteasy api -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.13.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>3.0.13.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.13.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>3.0.13.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-spring</artifactId>
<version>3.0.13.Final</version>
</dependency>
<!-- Resteasy Servlet Container Initializer -->
<!-- scope 'provided' for JBoss AS -->
<!-- <dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-servlet-initializer</artifactId>
<version>3.0.11.Final</version>
<scope>compile</scope>
</dependency> -->
<!-- slf4j and logger -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.1</version>
</dependency>
<!-- swagger for documentation -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.0</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<!-- commons -->
<dependency>
<groupId>com.mastek.commons</groupId>
<artifactId>commons</artifactId>
<version>1.0</version>
</dependency>
<!-- JSON to XML -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160212</version>
</dependency>
<!-- Gson: Java to Json conversion -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.2</version>
<scope>compile</scope>
</dependency>
<!-- swagger start -->
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-jaxrs_2.9.1</artifactId>
<version>${swagger-version}</version>
</dependency>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-annotations_2.9.1</artifactId>
<version>${swagger-version}</version>
</dependency>
<!-- swagger end -->
</dependencies>
<build>
<finalName>transaction-rs</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Persistence-config.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<context:property-placeholder ignore-resource-not-found="true" location="file:/sdt/configuration/services.properties, file:../../sdt/configuration/services.properties, classpath:application.properties" />
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${transaction.service.jdbc.driverClassName}" />
<property name="url" value="${transaction.service.jdbc.url}"/>
<property name="username" value="${transaction.service.jdbc.username}" />
<property name="password" value="${transaction.service.jdbc.password}"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list>
<value>com.mastek.commons.data.entity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
</beans>
This is the part of my DAOImpl.java:
package com.mastek.security.data.service;
import static com.mastek.commons.util.ApplicationConstants.DELIMITER;
import static com.mastek.commons.util.ApplicationConstants.END;
import static com.mastek.commons.util.ApplicationConstants.GET_WEEK;
import static com.mastek.commons.util.ApplicationConstants.REGISTER_USER;
import static com.mastek.commons.util.ApplicationConstants.START;
import static com.mastek.commons.util.ApplicationConstants.USER_ID;
import static com.mastek.commons.util.ApplicationConstants.VEFIFY_USER;
import static com.mastek.commons.util.ApplicationConstants.GET_USER_BY_EMAIL;
import java.util.Date;
import org.hibernate.Query;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.mastek.commons.data.dao.impl.AbstractDAO;
import com.mastek.commons.data.entity.VWLoginUser;
import com.mastek.commons.data.entity.VWUser;
import com.mastek.commons.data.entity.VWWeekEnding;
import com.mastek.commons.domain.UserDO;
import com.mastek.commons.domain.WeekDO;
import com.mastek.commons.exception.DataStoreException;
import com.mastek.commons.exception.SystemException;
import com.mastek.commons.util.CommonUtil;
import ma.glasnost.orika.MapperFacade;
/**
* The Class RegistrationDAOImpl.
*/
#Repository
public class RegistrationDAOImpl extends AbstractDAO implements RegistrationDAO
{
/** The Constant logger. */
private static final Logger logger = LoggerFactory.getLogger(RegistrationDAOImpl.class);
/** The mapper facade. */
#Autowired
private MapperFacade mapperFacade;
/**
* This method verifies logged in user.
*
* #param surname the surname
* #param userId the user id
* #return the user do
* #throws DataStoreException the data store exception
*/
#Override
public UserDO verifyUser(String surname, long userId) throws DataStoreException
{
logger.info(VEFIFY_USER + DELIMITER + USER_ID + userId + DELIMITER + START);
UserDO userDO = null;
Session session = openSession();
try
{
Query query = session.getNamedQuery("VWLoginUser.getUser");
query.setLong("userId", userId);
query.setString("surname", surname);
VWLoginUser user = (VWLoginUser) query.uniqueResult();
userDO = mapperFacade.map(user, UserDO.class);
}
catch (org.hibernate.exception.DataException de)
{
logger.error(VEFIFY_USER + DELIMITER + USER_ID + userId + DELIMITER + SystemException.Type.DE.getErrorCode() + DELIMITER + SystemException.Type.DE.getMessage());
logger.error(VEFIFY_USER, de);
throw new DataStoreException(new SystemException(SystemException.Type.DE, de));
}
catch (org.hibernate.exception.JDBCConnectionException jdbcce)
{
logger.error(VEFIFY_USER + DELIMITER + USER_ID + userId + DELIMITER + SystemException.Type.JDBCCE.getErrorCode() + DELIMITER + SystemException.Type.JDBCCE.getMessage());
logger.error(VEFIFY_USER, jdbcce);
throw new DataStoreException(new SystemException(SystemException.Type.JDBCCE, jdbcce));
}
catch (org.hibernate.exception.SQLGrammarException sqlge)
{
logger.error(VEFIFY_USER + DELIMITER + USER_ID + userId + DELIMITER + SystemException.Type.SQLGE.getErrorCode() + DELIMITER + SystemException.Type.SQLGE.getMessage());
logger.error(VEFIFY_USER, sqlge);
throw new DataStoreException(new SystemException(SystemException.Type.SQLGE, sqlge));
}
finally
{
session.clear();
session.close();
}
logger.info(VEFIFY_USER + DELIMITER + USER_ID + userId + DELIMITER + END);
return userDO;
}
}
This is my AbstractDAO.java:
package com.mastek.commons.data.dao.impl;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* The Class AbstractDAO.
*/
public abstract class AbstractDAO
{
/** The session factory. */
#Autowired
private SessionFactory sessionFactory;
/**
* Gets the session.
*
* #return the session
*/
protected Session getSession()
{
return sessionFactory.getCurrentSession();
}
/**
* Open session.
*
* #return the session
*/
protected Session openSession()
{
Session session = sessionFactory.openSession();
return session;
}
/**
* Persist.
*
* #param entity the entity
*/
public void persist(Object entity)
{
getSession().persist(entity);
}
/**
* Delete.
*
* #param entity the entity
*/
public void delete(Object entity)
{
getSession().delete(entity);
}
/**
* Gets the session factory.
*
* #return the session factory
*/
public SessionFactory getSessionFactory()
{
return sessionFactory;
}
/**
* Sets the session factory.
*
* #param sessionFactory the session factory
*/
public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
}
Related
Image of error I am receivingHello I am new to sending emails with Spring MVC. I am taking contact information in from a form and I want to be updated via email every time a new contact has been added to the database of contacts. taking in all the form parameters is working and I am able to add them to the database, but when trying to generate the email to send I am getting an Error creating bean exception. This seems to only happens when I add #Autowired to the JavaMailSender Object that I am creating in my controller. If I do not add #Autowired I get a null pointer exception probably because no object is being generated for the mail sender. Can anyone please help me how to figure this out?
I am including the code and XML files to hopefully get some insight.
import java.util.List;
import javax.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import co.clutch.contactform.dao.ContactDao;
import co.clutch.contactform.entity.Contact;
#Controller
public class ContactFormController {
static String emailToRecipient, emailSubject, emailMessage;
static final String emailFromRecipient = "camwess1#gmail.com";
static ModelAndView modelViewObj;
#Autowired
private ContactDao contactDao;
#Autowired
private JavaMailSender mailSenderObj;
// Show contactForm
#RequestMapping("/")
public ModelAndView showContactForm() {
ModelAndView mav = new ModelAndView("contact_form");
return mav;
}
#RequestMapping("submitform/create/{contact}")
public ModelAndView submitContactForm(#RequestParam(value = "name") String
contactName,
#RequestParam(value = "number") String phoneNumer,
#RequestParam(value = "email") String email,
#RequestParam(value = "industry") String industry) {
// Create new Contact Object
Contact contact = new Contact(contactName, phoneNumer, email, industry);
System.out.println(contact.toString());
// Create contact in database
contactDao.create(contact);
List<Contact> contacts = contactDao.findAll();
// email information
// Reading Email Form Input Parameters
emailSubject = "New Lead";
emailMessage = "You have a new lead from " + contact.getContactName();
emailToRecipient = "test#test.com";
// Logging The Email Form Parameters For Debugging Purpose
System.out.println("\nReceipient?= " + emailToRecipient + ", Subject?= "
+ emailSubject + ", Message?= "
+ emailMessage + "\n");
mailSenderObj.send(new MimeMessagePreparator() {
public void prepare(MimeMessage mimeMessage) throws Exception {
MimeMessageHelper mimeMsgHelperObj = new
MimeMessageHelper(mimeMessage, true, "UTF-8");
mimeMsgHelperObj.setTo(emailToRecipient);
mimeMsgHelperObj.setFrom(emailFromRecipient);
mimeMsgHelperObj.setText(emailMessage);
mimeMsgHelperObj.setSubject(emailSubject);
}
});
System.out.println("\nMessage Send Successfully.... Hurrey!\n");
ModelAndView mav = new ModelAndView("showcontacts", "contacts",
contacts);
return mav;
}
Here is the app-servelet.xml file
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-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="com.jcg.spring.mvc.email" />
<!-- Spring Email Sender Bean Configuration -->
<bean id="mailSender"
class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.gmail.com" />
<property name="port" value="587" />
<property name="username" value="test#test.com" />
<property name="password" value="password" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.debug">true</prop>
<prop key="mail.transport.protocol">smtp</prop>
<prop
key="mail.smtp.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop>
<prop key="mail.smtp.socketFactory.port">465</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
</props>
</property>
</bean>
<!-- Spring Email Attachment Configuration -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- Maximum Upload Size In Bytes -->
<property name="maxUploadSize" value="20971520" />
<!-- Maximum Size Of File In Memory (In Bytes) -->
<property name="maxInMemorySize" value="1048576" />
</bean>
<!-- Resolves Views Selected For Rendering by #Controllers to *.jsp Resources
in the /WEB-INF/ Folder -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- Send Email Exception Resolver i.e. In Case Of Exception The Controller
Will Navigate To 'error.jsp' & Will Display The Exception Message -->
<bean
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver
">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">error</prop>
</props>
</property>
</bean>
Here is a copy of my web.xml file
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
<display-name>Spring Mvc Email Example</display-name>
<!-- Spring Configuration - Processes Application Requests -->
<servlet>
<servlet-name>SpringController</servlet-name>
<servlet-
class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringController</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Welcome File List -->
<welcome-file-list>
<welcome-file>contact_form.jsp</welcome-file>
</welcome-file-list>
</web-app>
Here is a copy of my dependencies
<?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>co.clutch</groupId>
<artifactId>contact-form</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>contact-form</name>
<description>Demo project for Spring Boot</description>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</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>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- All Mail Related Stuff + Much more -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<!-- Java Mail Dependency -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
</build>
</project>
I am trying to have the email send after the contact Object is added to the database. If I take #autowired off it returns a null pointer exception as if it's generating an object for sending the email.
Add below dependency in your pom and remove others I defined below should work
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
and remove below:
<!-- Java Mail Dependency -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
STEP2 : move out your mail properties in application.properties instead of servlet xml.
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.host=************
spring.mail.port=587
spring.mail.username=********************
spring.mail.password=*****************
spring.mail.protocol=smtp
spring.mail.defaultEncoding=UTF-8
spring.mail.smtp.auth=true
So I'm trying to use Spring to manage hibernate transactions for the first time, and something's going wrong. I'm not sure what. I've looked at a bunch of similar answers on this site and nothing I've seen seems to be right.
So, I'm gonna copy and paste a bunch of my code with some explanations and ask for help here.
Here is a stack trace of the exception I'm getting. Essentially, It seems that it's trying to find org.hibernate.engine.transaction.spi.transactioncontext, and can't.
Exception stack trace
EXCEPTION: Could not open Hibernate Session for transaction; nested exception is java.lang.NoClassDefFoundError: org/hibernate/engine/transaction/spi/TransactionContext
org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:544)
org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:427)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
com.sun.proxy.$Proxy42.getSavedPortfolios(Unknown Source)
io.craigmiller160.stockmarket.controller.StockMarketController.showOpenPortfolioDialog(StockMarketController.java:994)
io.craigmiller160.stockmarket.controller.StockMarketController.parseEvent(StockMarketController.java:431)
io.craigmiller160.stockmarket.controller.StockMarketController.processEvent(StockMarketController.java:336)
io.craigmiller160.mvp.concurrent.AbstractConcurrentListenerController$1.run(AbstractConcurrentListenerController.java:209)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
Now, I've searched this site, and the big thing I saw was that this means I have a dependency wrong in my pom.xml. The thing is, I have the most up-to-date version of the hibernate-core dependency in my pom. From what I've read, that's what I need for this class.
pom.xml dependencies
<dependencies>
<!-- JUnit Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- MVP Framework -->
<dependency>
<groupId>io.craigmiller160.mvp</groupId>
<artifactId>mvp-framework</artifactId>
<version>2.1.1</version>
</dependency>
<!-- MigLayout -->
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout-swing</artifactId>
<version>5.0</version>
</dependency>
<!-- JFreeChart -->
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.19</version>
</dependency>
<!-- Java Concurrency In Practice Annotations -->
<dependency>
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
</dependency>
<!-- Joda Time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.8.2</version>
</dependency>
<!-- MySQL ConnectorJ -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
<!-- Spring Framework Core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Framework Beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Framework Context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Hibernate Core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.1.Final</version>
</dependency>
<!-- XML Framework -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- Code Generation library -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
<!-- Apache Commons Logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- LOG4J API -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- LOG4J Core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- SLF4J/LOG4J Binding -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- LOG4J/Commons Logging Binding -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- SLF4J API -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<!-- Spring ORM -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- AspectJ Runtime -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!-- AspectJ Weaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!-- Apache Database Connection Pooling -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies>
Also, I'm adding the actual method in my DAO that I'm calling. This method is what is attempting to run when the exception is thrown.
DAO method:
#Transactional
#Override
#SuppressWarnings("unchecked") //hibernate list() method doesn't support generics
public List<String> getSavedPortfolios() throws HibernateException {
List<String> portfolioNames = new ArrayList<>();
List<SQLPortfolioModel> portfolioList = sessionFactory.getCurrentSession()
.createCriteria(PortfolioModel.class)
.list();
for(SQLPortfolioModel portfolio : portfolioList){
int id = portfolio.getUserID();
String name = portfolio.getPortfolioName();
BigDecimal netWorth = portfolio.getNetWorth();
Calendar timestamp = portfolio.getTimestamp();
String fileName = String.format("%1$d-%2$s-%3$s-"
+"%4$s", id, name, moneyFormat.format(netWorth),
timestampFormat.format(timestamp.getTime()));
portfolioNames.add(fileName);
}
return portfolioNames;
}
Lastly, here is my spring-context-data.xml. It contains all the configuration for my data beans for spring, plus the transaction stuff:
spring-context-data.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: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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- Sets annotation-driven transactions -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- DataSource object for providing database connections -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/stockmarket"/>
<property name="username" value="stockmarket"/>
<property name="password" value="stockmarket"/>
</bean>
<!-- SessionFactory object for creating sessions for database access -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- <property name="configLocation" value="classpath:hibernate.cfg.xml"/>-->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="connection.pool_size">1</prop>
<prop key="show_sql">false</prop>
<!-- Might need this one below for transactions, not sure yet -->
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>io.craigmiller160.stockmarket.stock.AbstractStock</value>
<value>io.craigmiller160.stockmarket.stock.OwnedStock</value>
<value>io.craigmiller160.stockmarket.stock.DefaultStock</value>
<value>io.craigmiller160.stockmarket.stock.DefaultOwnedStock</value>
<value>io.craigmiller160.stockmarket.model.PortfolioModel</value>
<value>io.craigmiller160.stockmarket.model.SQLPortfolioModel</value>
</list>
</property>
</bean>
<!-- Hibernate Transaction Manager -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- HibernateDAO class for performing database operations -->
<bean id="hibernateDao" class="io.craigmiller160.stockmarket.controller.HibernatePortfolioDAO"
destroy-method="closeFactory">
<constructor-arg ref="sessionFactory"/>
</bean>
</beans>
So I just have no idea why this is happening. I've double and triple checked what I did versus what I'm seeing online, and I can't see the mistake. This is my first time trying to use Spring transaction management. Any help would be greatly appreciated.
PS. I'm using Spring 4 & Hibernate 5 together, if that makes a difference.
In your POM you are depending on Hibernate 5, but in your transaction manager, you are using Hibernate 4.
Change your transacation manager to match your pom (i.e. from hibernate4 to hibernate5):
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
If that causes a class not found error, upgrade your spring framework to 4.2.2
The class it is looking for is referring to a class that only exists in Hibernate 4.x
http://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/engine/transaction/spi/package-summary.html
But no more in 5.x
http://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/engine/transaction/spi/package-summary.html
So I think you might be mixing Hibernate 4 and 5 dependencies. I don't think you can just switch the hibernate version without reviewing all of its dependencies.
You are using hibernate-5 but you are asking spring to use hibernate-4 sessionFactory
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
and transaction manager
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
Not sure if this is the problem, but since you think is something related to the pom.xml try adding the hibernate's entity manager dependency. I compared your pom.xml with mine and, with regards to the hibernate's dependencies, this is the one lacking.
I was getting the same problem and my problem get solved by updating
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
I keep getting this error, here are my files
hibernate.cfg.xml
<!-- Database connection settings -->
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">jdbc:postgresql://localhost:5432/postgres</property>
<property name="connection.username">postgres</property>
<property name="connection.password">postgres></property>
<property name="hibernate.default_schema">hibernate_test</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.PostgreSQL82Dialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping class="com.de.entity.Employee"></mapping>
</session-factory>
HibernateUtil.java
package com.de.config;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Sets up the connection the DB and Hibernate
* #author de
*
*/
public class HibernateUtil {
private static final Logger logger = LoggerFactory.getLogger(HibernateUtil.class);
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
logger.info("Creating Hibernate Session Factory");
try{
// Create the SessionFactory form hibernate.cfg.xml
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
logger.info("Hibernate Configuration loaded");
logger.info("Configuration: " + configuration.getProperties());
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
} catch (Throwable ex) {
logger.error("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Here is a better snippet of the error
09:47:23,829 WARN DriverManagerConnectionProviderImpl:93 - HHH000402: Using Hibernate built-in connection pool (not for production use!)
09:47:23,846 INFO DriverManagerConnectionProviderImpl:166 - HHH000401: using driver [org.postgresql.Driver] at URL [jdbc:postgresql://localhost:5432/postgres]
09:47:23,848 INFO DriverManagerConnectionProviderImpl:175 - HHH000046: Connection properties: {user=postgres, password=****}
09:47:23,849 INFO DriverManagerConnectionProviderImpl:180 - HHH000006: Autocommit mode: false
09:47:23,852 INFO DriverManagerConnectionProviderImpl:102 - HHH000115: Hibernate connection pool size: 1 (min=1)
09:47:23,922 ERROR HibernateUtil:35 - Initial SessionFactory creation failed.org.hibernate.exception.JDBCConnectionException: Error calling Driver#connect
I've been trying my best to figure out what this issue is.
I downloaded Navicat for Postgres and I was able to successfully connect to it using the connection url and username/password. So I narrowed out the connection information being incorrect.
Just for completion...
Here is 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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.de.test</groupId>
<artifactId>test</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>testMaven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<slf4jVersion>1.7.7</slf4jVersion>
</properties>
<dependencies>
<!-- Persistence -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>ejb3-persistence</artifactId>
<version>1.0.2.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.5.Final</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<!-- <dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.0.2.GA</version>
</dependency> -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1100-jdbc41</version>
</dependency>
<dependency>
<groupId>com.github.dzwicker.dart</groupId>
<artifactId>dart-maven-plugin</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
<!-- REST / WEB -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.8</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.8</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.8</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.2.3</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4jVersion}</version>
</dependency>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>test</finalName>
</build>
</project>
Well I feel like an idiot.
There was a typo in the password.
<property name="connection.password">postgres></property>
I didn't realize it until I stepped through the jdbc classes and discovered the psql error.
Verify if database is on. That happened in my case
I'm creating simple java web app that writes one row of data to HBase table via JPA2 (using Datanucleus) everything working except it writing 2 duplicate rows instead of just writing 1 row
Results
ROW COLUMN+CELL
402881813acfed78013acfed78e00000 column=ACCOUNT_TABLE:FIRSTNAME, timestamp=1352108207916, value=testname
402881813acfed78013acfed78e00000 column=ACCOUNT_TABLE:ID, timestamp=1352108207916, value=402881813acfed78013acfed78e00000
402881813acfed78013acfed78e00000 column=ACCOUNT_TABLE:LASTNAME, timestamp=1352108207916, value=testname2
402881813acfed78013acfed78e00000 column=ACCOUNT_TABLE:LEVEL, timestamp=1352108207916, value=\x00\x00\x00\x03
402881813acfed78013acfedf7e20001 column=ACCOUNT_TABLE:FIRSTNAME, timestamp=1352108210172, value=testname
402881813acfed78013acfedf7e20001 column=ACCOUNT_TABLE:ID, timestamp=1352108210172, value=402881813acfed78013acfedf7e20001
402881813acfed78013acfedf7e20001 column=ACCOUNT_TABLE:LASTNAME, timestamp=1352108210172, value=testname2
402881813acfed78013acfedf7e20001 column=ACCOUNT_TABLE:LEVEL, timestamp=1352108210172, value=\x00\x00\x00\x03
2 row(s) in 0.1270 seconds
Datanucleus version in pom.xml
<org.datanucleus-version>3.1.1</org.datanucleus-version>
dependencies in pom.xml
<dependencies>
<!-- JPA 2.0 Spec -->
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jpa_2.0_spec</artifactId>
<version>1.1</version>
</dependency>
<!-- JDO API -->
<dependency>
<groupId>javax.jdo</groupId>
<artifactId>jdo-api</artifactId>
<version>3.0</version>
</dependency>
<!-- DataNucleus HBase -->
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-hbase</artifactId>
<version>${org.datanucleus-version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.0.4</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase</artifactId>
<version>0.94.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.3</version>
</dependency>
<!-- DataNucleus Core -->
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-core</artifactId>
<version>${org.datanucleus-version}</version>
<scope>runtime</scope>
</dependency>
<!-- DataNucleus Enhancer -->
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-enhancer</artifactId>
<version>${org.datanucleus-version}</version>
</dependency>
<!-- DataNucleus JPA api -->
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jpa</artifactId>
<version>${org.datanucleus-version}</version>
</dependency>
Plugin in pom.xml
<plugin>
<groupId>org.datanucleus</groupId>
<artifactId>maven-datanucleus-plugin</artifactId>
<version>${org.datanucleus-version}</version>
<configuration>
<api>JPA</api>
<log4jConfiguration>${basedir}/log4j.properties</log4jConfiguration>
<verbose>true</verbose>
<persistenceUnitName>hbase-test</persistenceUnitName>
</configuration>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
</plugin>
Account.java
package org.test.model;
import javax.persistence.*;
import java.io.Serializable;
#Entity
#Table(name = "ACCOUNT_TABLE")
public class Account implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "ACCOUNT_TABLE:ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private String id;
#Column(name = "ACCOUNT_TABLE:FIRSTNAME")
private String firstName;
#Column(name = "ACCOUNT_TABLE:LASTNAME")
private String lastName;
#Column(name = "ACCOUNT_TABLE:LEVEL")
private int level = 0;
public Account() {
}
public Account(String firstName, String lastName, int level) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.level = level;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="hbase-test" transaction-type="RESOURCE_LOCAL">
<provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider>
<mapping-file>org/test/model/orm.xml</mapping-file>
<class>org.test.model.Account</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="datanucleus.storeManagerType" value="hbase" />
<property name="datanucleus.ConnectionURL" value="hbase:localhost:60010"/>
<property name="datanucleus.ConnectionUserName" value=""/>
<property name="datanucleus.ConnectionPassword" value=""/>
<property name="datanucleus.autoCreateSchema" value="true"/>
<property name="datanucleus.autoCreateTables" value="true" />
<property name="datanucleus.autoCreateColumns" value="true" />
<property name="datanucleus.validateTables" value="true"/>
<property name="datanucleus.validateConstraints" value="false"/>
<property name="datanucleus.Optimistic" value="false"/>
<property name="datanucleus.Multithreaded" value="true" />
</properties>
</persistence-unit>
</persistence>
orm.xml
<?xml version="1.0" encoding="UTF-8" ?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0">
<description>JPA Mapping file for Test</description>
<package>org.test.model</package>
<entity class="org.test.model.Account" name="Account">
<table name="ACCOUNT_TABLE" />
<attributes>
<id name="id">
<generated-value strategy="AUTO"/>
</id>
<basic name="firstName">
<column name="ACCOUNT_TABLE:FIRSTNAME"/>
</basic>
<basic name="lastName">
<column name="ACCOUNT_TABLE:LASTNAME"/>
</basic>
<basic name="level">
<column name="ACCOUNT_TABLE:LEVEL"/>
</basic>
</attributes>
</entity>
</entity-mappings>
TestAddAccountRow.java
package org.test.app;
import org.test.model.Account;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class TestAddAccountRow {
public void addAccount() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hbase-test");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = null;
Account a2 = new Account("testname","testname2",3);
tx = em.getTransaction();
tx.begin();
em.persist(a2);
tx.commit();
}
}
UPDATE
#Datanucleus
I had code in spring mvc controller calling DAO (adding Account object), i don't know why but this was causing the duplicate rows, Datanucleus works perfectly.
While i couldn't find why it was creating duplicate rows, i swap out Datanucleus for Kundera it seems to solve the problem of duplicate rows
I think there a bug in Datanucleus
Kundera version number
<kundera-version>2.1</kundera-version>
pom.xml dependencies
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.impetus.core</groupId>
<artifactId>kundera-core</artifactId>
<version>${kundera-version}</version>
</dependency>
<dependency>
<groupId>com.impetus.client</groupId>
<artifactId>kundera-hbase</artifactId>
<version>${kundera-version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.impetus.kundera.rest</groupId>
<artifactId>kundera-rest</artifactId>
<version>${kundera-version}</version>
</dependency>
<!-- HBase and Hadoop -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.0.4</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase</artifactId>
<version>0.94.0</version>
</dependency>
persistence.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright (C) 2010 Bartosch Warzecha, Matthias Weßendorf
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="hbase">
<provider>com.impetus.kundera.KunderaPersistence</provider>
<class>org.test.model.Account</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="kundera.nodes" value="localhost" />
<property name="kundera.port" value="60010" />
<property name="kundera.keyspace" value="test" />
<property name="kundera.dialect" value="hbase" />
<property name="kundera.client.lookup.class" value="com.impetus.client.hbase.HBaseClientFactory" />
<property name="kundera.cache.provider.class"
value="com.impetus.kundera.cache.ehcache.EhCacheProvider" />
<property name="kundera.cache.config.resource" value="/ehcache-test.xml" />
<property name="kundera.ddl.auto.prepare" value="create" />
</properties>
</persistence-unit>
</persistence>
I am using Spring MVC with JSON as specified in Ajax Simplification Spring 3.0 article.
After so many attempts and variations of my code depending on advice found on various forums, my code still doesn't work.
I keep on getting the following error: (406) The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ().
I have in my appconfig.xml as required.
app-config.xml
<context:component-scan base-package="org.ajaxjavadojo" />
<!-- Configures Spring MVC -->
<import resource="mvc-config.xml" />
mvc-config.xml
<mvc:annotation-driven />
<!-- Forwards requests to the "/" resource to the "index" view -->
<mvc:view-controller path="/" view-name="index"/>
<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="html" value="text/html"/>
<entry key="json" value="application/json"/>
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
</bean>
This is what I have for my controller
#Controller
#RequestMapping (value = "/convert")
public class ConversionController {
#RequestMapping(method=RequestMethod.GET)
public String getConversionForm(){
return "convertView";
}
#RequestMapping(value = "/working", headers="Accept=application/json", method=RequestMethod.GET)
public #ResponseBody Conversion getConversion(){
Conversion d = new Conversion("d");
return d;
}
}
jsp jquery call
function convertToDecimal(){
$.getJSON("convert/working", {key: "r"}, function(aConversion){
alert("it worked.");
$('#decimal').val(aConversion.input);
});
}
I would really appreciate any input on this issue.
Thank you
To return JSON response from #ResponseBody-annotated method, you need two things:
<mvc:annotation-driven /> (you already have it)
Jackson JSON Mapper in the classpath
You don't need ContentNegotiatingViewResolver and headers in #RequestMapping.
I had this problem after I upgraded Spring to 4.1.x from 3.2.x. I fixed by upgrading Jackson from 1.9.x to 2.2.x (fasterxml)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.3</version>
</dependency>
Try remove the header limitation for Accept, put a breakpoint and see what's the actual value. Or do this with FireBug.
Also take a look at this jquery issue
Add org.springframework.http.converter.json.MappingJacksonHttpMessageConverter and org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter to DispatcherServlet-servlet.xml. and refer to the the first one in the second using
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jacksonMessageConverter"/>
</list>
</property>
</bean>
I too got this error and while debugging deep down into the rabbit hole i came across this exception
java.lang.IllegalArgumentException: Conflicting getter definitions for property "error": com.mycomp.model.OutputJsonModel#isError(0 params) vs com.mycomp.model.OutputJsonModel#getError(0 params)
So basically in my java bean i had something like the following:
private boolean isError;
private ErrorModel error;
public ErrorModel getError() {
return error;
}
public void setError(ErrorModel error) {
this.error = error;
}
public boolean isError() {
return isError;
}
public void setError(boolean isError) {
this.isError = isError;
}
Changing one of the error member variable name to something else solved the issues.
I had this problem too, you have to add <mvc:annotation-driven /> in your configuration xml
and
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.databind-version}</version>
</dependency>
in your pom.xml
I have used java configuration and i got this same error. I have missed to add the #EnableWebMvc to the configuration file. This error is resolved after i add the #EnableWebMvc in my webconfig file.
Also the Object that is returned from your Spring Controller, should have proper getter and setter methods.
package com.raghu.dashboard.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import com.raghu.dashboard.dao.ITaskDAO;
import com.raghu.dashboard.dao.TaskDAOImpl;
#Configuration
#EnableWebMvc //missed earlier...after adding this it works.no 406 error
#ComponentScan(basePackages = { "com.raghu.dashboard.api", "com.raghu.dashboard.dao" })
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() { return null;}
protected Class<?>[] getServletConfigClasses() {
return new Class[] { MongoConfiguration.class};
}
protected String[] getServletMappings() {
return new String[]{"*.htm"};
}
#Bean(name = "taskDao")
public ITaskDAO taskDao() {
return new TaskDAOImpl();
}
#Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".jsp");
return resolver;
}
}
AppInitializer.java
package com.raghu.dashboard.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class AppInitalizer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext)
throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/*");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(com.raghu.dashboard.config.WebConfig.class);
context.scan("com.raghu.dashboard.api");
return context;
}
}
Also make sure the Object that is returned, has the proper getter and setter.
Example:
#RequestMapping(value = "/list", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity<TaskInfo> findAll() {
logger.info("Calling the findAll1()");
TaskInfo taskInfo = dashboardService.getTasks();
HttpHeaders headers = new HttpHeaders();
headers.add("Access-Control-Allow-Origin", "*");
ResponseEntity<TaskInfo> entity = new ResponseEntity<TaskInfo>(taskInfo,
headers, HttpStatus.OK);
logger.info("entity is := " + entity);
return entity;
}
TaskInfo object should have proper getter and setter. if not, 406 error will be thrown.
POM File for Reference:
<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.raghu.DashBoardService</groupId>
<artifactId>DashBoardService</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>DashBoardService Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<!-- Spring -->
<spring-framework.version>4.0.6.RELEASE</spring-framework.version>
<jackson.version>2.4.0</jackson.version>
<jaxb-api.version>2.2.11</jaxb-api.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.10.1</version>
</dependency>
<!-- Spring Data Mongo Support -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.4.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-dao</artifactId>
<version>2.0.3</version>
</dependency>
<!-- Jackson mapper -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>1.7.1</version>
</dependency>
<!-- Log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.5.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>DashBoardService</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
issue is not related to jquery . even bug is saying it is server side issue . please make sure that following 2 jar present in class path :-
jackson-core-asl-1.9.X.jar
jackson-mapper-asl-1.9.X.jar
I also faced this same issue and I downloaded this [jar]: (http://www.java2s.com/Code/Jar/j/Downloadjacksonall190jar.htm)! and placed in lib folder and the app works like a charm :)
See my answer to a similar problem here with Spring MVC interpreting the extension of the URI and changing the expected MIME type produced behind the scene, therefore producing a 406.
Well, The answers on this page might be right but they didn't expatiate well. This is what I did
I added this to my pom.xml
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.8</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.8</version>
</dependency>
Then I added headers to my RequestMapping like below
#RequestMapping(value="/admin/getGallery", method = RequestMethod.GET, headers={"Content-Type=application/json"})
Then in my jquery ajax I added - contentType: "application/json", so it looks like
jQuery.ajax({
type:'GET',
url:"getGallery.html",
data: "designId="+designId,
processData:false,
contentType: "application/json",
//dataType: "json",
success:function(data){
console.log(data);
},
error : function(e) {
console.log("ERROR: ", e);
},
});
Then in my servlet I added
<bean id="jsonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
<!-- Bind the return value of the Rest service to the ResponseBody. -->
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list id="beanList">
<ref bean="jsonHttpMessageConverter" />
</util:list>
</property>
</bean>
If you have problem with util tag in your servlet just just add in the same servlet file
xmlns:util="http://www.springframework.org/schema/util"
and
xsi:schemaLocation="http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
As said by axtavt, mvc:annotation-driven and jackson JSON mapper are all that you need. I followed that and got my application to return both JSON and XML strings from the same method without changing any code, provided that there are #XmlRootElement and #XmlElement in the object you are returning from the controller. The difference was in the accept parameter passed in the request or header. To return xml, any normal invocation from the browser will do it, otherwise pass the accept as 'application/xml'. If you want JSON returned, use 'application/json' in the accept parameter in request.
If you use firefox, you can use tamperdata and change this parameter
Using jQuery , you can set contentType to desired one (application/json; charset=UTF-8' here) and set same header at server side.
REMEMBER TO CLEAR CACHE WHILE TESTING.
Instead of #RequestMapping(...headers="Accept=application/json"...) use #RequestMapping(... , produces = "application/json")