I have a problem about integrating Hibernate with Spring:
My hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/CODEL</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.current_session_context_class">
org.springframework.orm.hibernate4.SpringSessionContext
</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<mapping resource="com/model/Contact.hbm.xml" />
</session-factory>
</hibernate-configuration>
My 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:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="contactdao" class="com.dao.ContactDAO" scope="prototype" />
<bean id="userdao" class="com.dao.UserDAO" scope="prototype" />
<bean id="groupdao" class="com.dao.GroupDAO" scope="prototype" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/CODEL"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation">
<!-- chemin vers le fichier hibernate de config. ça évite d'avoir un composant
datasource -->
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="get*" read-only="true" timeout="-1" />
<tx:method name="sav*" propagation="REQUIRED" />
<tx:method name="find*" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor pointcut="execution(* com.dao.ContactDAO.*(..))"
advice-ref="txAdvice" />
</aop:config>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="mySessionFactory"></property>
<property name="checkWriteOperations" value="false" />
</bean>
<bean id="contactDAO" class="com.dao.ContactDAO">
<property name="hibernateTemplate" ref="hibernateTemplate" />
</bean>
</beans>
My dao
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.orm.hibernate4.support.HibernateDaoSupport;
import com.model.Contact;
import com.model.Entreprise;
import com.model.PhoneNumber;
import com.util.HibernateUtil;
public class ContactDAO extends HibernateDaoSupport {
private HibernateTemplate hibernateTemplate;
public ContactDAO() {
}
public void setHibernateTemplate(SessionFactory sessionFactory) {
this.hibernateTemplate = new HibernateTemplate(sessionFactory);
}
public List<Contact> listAllContacts() {
List<Contact> listContacts = (List<Contact>) this.hibernateTemplate
.find("from CODEL.Contact");
return listContacts;
}
}
I've got an error NullPointerException at the line of this.hibernateTemplate.find... By println, I've seen it null. Thanks for any suggestion and explanation why my code produced this error.
Can you please update your ContactDAO setHibernateTemplate method to set the hibernateTemplate, instead of creating a new HibernateTemplate, for example
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
currently your setter method is taking sessionFactory, so its not calling the actual setter for hibernate template, which could be causing the null pointer exception.
Let's say you have to tell Spring how different components communicate between them.You need annotations to linked them together.
The easiest way is letting Spring detects these links itself.
So in applicationContext.xml, add this line of code :
<context:component-scan base-package="com.example.pkg" />
Then, Spring will search for every components in this package.
You need also declare the existence of your comopents.
#Repository(value = "contactDAO")
public class ContactDAO extends HibernateDaoSupport
And you have to link the bean created in context to your class attribut:
#Autowired
private HibernateTemplate hibernateTemplate;
Then you can use this HibernateTemplate object without setMethod because it initialization is done by Spring.
Related
I try to tests how hibernate Entities are persisted to database. I have 5 tests for 3 Entitites. All my attempts are unsuccessful((( I tried to use #Transactional annotation to bind each test to one transaction. But I could not (tried all combinations). Now I try to test it manually creating sessions and transactions. But now problem is that I dont know how to create one session for all tests. I tried #BeforeClass, but here problem is that it is static and I use Spring beans for session creation. Any ideas how I can test hibernate Entities?
You can use a dedicated database like HSQLDB for testing you entities via DAO test classes.
You will need a:
Maven test profile
Spring configuration file (test context)
Script SQL to insert some data
DAO class test.
Maven test profile :
<profile>
<id>test</id>
<properties>
<jpa.dialect>org.springframework.orm.jpa.vendor.HibernateJpaDialect</jpa.dialect>
<jpa.vendor.adapter>HibernateJpaVendorAdapter</jpa.vendor.adapter>
<jdbc.dialect>org.hibernate.dialect.HSQLDialect</jdbc.dialect>
<jdbc.url>jdbc:hsqldb:mem:testDatabase</jdbc.url>
<jdbc.driver>org.hsqldb.jdbcDriver</jdbc.driver>
<jdbc.username>sa</jdbc.username>
<jdbc.password></jdbc.password>
<jdbc.format_sql>true</jdbc.format_sql>
<jdbc.show_sql>true</jdbc.show_sql>
<!-- import.sql is read : it must have this name and be in classpath -->
<jpa.generateDdl>true</jpa.generateDdl>
<hibernate.format_sql>true</hibernate.format_sql>
<hibernate.hbm2ddl.auto>create</hibernate.hbm2ddl.auto>
</properties>
</profile>
Spring test-applicationContext.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:jpa="http://www.springframework.org/schema/data/jpa"
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-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
<!-- enables interpretation of the #PersistenceUnit/#PersistenceContext
annotations providing convenient access to EntityManagerFactory/EntityManager -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<context:component-scan base-package="foo.bar.dao">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Repository" />
</context:component-scan>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="jpaLibrary" />
<property name="jpaDialect">
<bean class="${jpa.dialect}" />
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.${jpa.vendor.adapter}">
<property name="showSql" value="${jdbc.show_sql}" />
<property name="databasePlatform" value="${jdbc.dialect}" />
<!-- On genere la BDD au demarrage -->
<property name="generateDdl" value="${jpa.generateDdl}" />
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager" />
<context:spring-configured />
<context:annotation-config />
</beans>
import.sql (authors for instance):
INSERT INTO `testDatabase`.`authors`(author_id, name) VALUES
(1, "JRR Tolkien"),
(2, "Albert Camus"),
(3, "Victor Hugo");
...
Finally, the class to test your DAO (then entities) :
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import foo.bar.dao.BookDao;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "/test-applicationContext.xml" })
public class BookDaoTest extends AbstractTransactionalJUnit4SpringContextTests {
#Autowired
private BookDao bookDao;
private int initialSize = 0;
#Before
public void init() {
initialSize = bookDao.findAll().size();
}
#Test
public void getAllBooks() {
assertEquals(12, initialSize);
}
...
}
I am using hibernate along side spring to configure the session factory and hibernate transaction manager, below mentioned is the apllication-context 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"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd">
<beans profile="nondev,dev">
<context:annotation-config />
<context:component-scan base-package="com.woodmac" />
<import resource="classpath:spring/applicationContext-soap.xml" />
<import resource="classpath:spring/applicationContext-cache.xml" />
<import resource="classpath:spring/applicationContext-mail.xml" />
<import resource="classpath:spring/applicationContext-batchJobs.xml" />
<bean name="ecommSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="ecommDataSource" />
<property name="hibernateProperties" ref="hibernateProperties" />
<property name="packagesToScan" value="com.woodmac" />
</bean>
<bean name="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties" ref="hibernateProperties" />
<property name="packagesToScan" value="com.woodmac" />
</bean>
<bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<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>
<prop key="hibernate.use_sql_comments">${hibernate.use_sql_comments}</prop>
<prop key="hibernate.connection.release_mode">after_statement</prop>
</props>
</property>
</bean>
<!--
Source: http://static.springsource.org/spring/docs/3.0.0.RC3/reference/html/ch12s03.html
A DataSource is part of the JDBC specification and is a generalized connection factory. It allows a container or a
framework to hide connection pooling and transaction management issues from the application code.
NOTE: DriverManagerDataSource
class is not an actual connection pool; it does not actually pool Connections. It just serves as simple replacement for a
full-blown connection pool, implementing the same standard interface, but creating new Connections on every call. -->
<!--
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="minPoolSize" value="${hibernate.c3p0.minPoolSize}" />
<property name="maxPoolSize" value="${hibernate.c3p0.maxPoolSize}" />
<property name="maxIdleTime" value="${hibernate.c3p0.idleTestPeriod}" />
<property name="maxConnectionAge" value="${hibernate.c3p0.maxConnectionAge}" />
<property name="maxStatements" value="${hibernate.c3p0.max_statement}" />
<property name="testConnectionOnCheckout" value="${hibernate.c3p0.testConnectionOnCheckout}" />
<property name="preferredTestQuery" value="${hibernate.c3p0.preferredTestQuery}" />
<property name="debugUnreturnedConnectionStackTraces" value="${hibernate.c3p0.debug}" />
</bean>
-->
<!-- This bean is the Spring Hibernate transaction manager that will handle transaction related boilerplate code and wiring
for us. We needed to define the session factory that the transaction manager will use to create sessions -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" depends-on="sessionFactory">
</bean>
<!-- This bean is the spring hibernate transaction manager for new session factory -->
<bean id="ecommTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="ecommSessionFactory" depends-on="sessionFactory">
</bean>
<!-- Transaction Management tx:annotation-driven element defines that we are declaring transactions using annotations in
our classes. -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<!-- Transaction management for the ecommerce transactions -->
<tx:annotation-driven transaction-manager="ecommTransactionManager" proxy-target-class="true" />
<!-- the transactional advice (i.e. what 'happens'; see the <aop:advisor/> bean below) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- all methods starting with 'get', 'select', 'find' are read-only -->
<tx:method name="get*" read-only="true" propagation="SUPPORTS" />
<tx:method name="select*" read-only="true" propagation="SUPPORTS" />
<tx:method name="find*" read-only="true" propagation="SUPPORTS" />
<tx:method name="fetch*" read-only="true" propagation="SUPPORTS" />
<!-- other methods use the default transaction settings -->
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
</beans>
<!-- Note: Only use the DriverManagerDataSource class should only be used for testing purposes since it does not provide
pooling and will perform poorly when multiple requests for a connection are made. -->
<beans profile="dev-notinuse">
<!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}">
</bean> -->
<!-- <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${portal.ds.jndi}"/>
</bean> -->
</beans>
<beans profile="nondev, dev">
<jee:jndi-lookup id="ecommDataSource" jndi-name="${ecommerce.ds.jndi}" lookup-on-startup="true" lazy-init="false" expected-type="javax.sql.DataSource" proxy-interface="javax.sql.DataSource"/>
<jee:jndi-lookup id="dataSource" jndi-name="${portal.ds.jndi}" lookup-on-startup="true" lazy-init="false" expected-type="javax.sql.DataSource" proxy-interface="javax.sql.DataSource"/>
</beans>
</beans>
Now in the test DAO that I have written to call a stored procedure ---
package com.woodmac.component.event.dao.impl;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import oracle.jdbc.OracleTypes;
import org.hibernate.Session;
import org.hibernate.jdbc.Work;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.woodmac.component.event.dao.IEventDAO;
import com.woodmac.generic.dao.impl.EcommDaoImpl;
/**
* The Class EventDAOImpl.
*/
#Component
#Qualifier("eventDAO")
#Transactional
#DependsOn("ecommSessionFactory")
public class EventDAOImpl extends EcommDaoImpl implements IEventDAO{
public Integer callSqlBlock(){
Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
final Integer outputValue =1;
session.doWork(new Work() {
#Override
public void execute(Connection conn)
throws SQLException {
CallableStatement stmt = conn.prepareCall("? = call test(?)");
stmt.registerOutParameter(1, OracleTypes.INTEGER);
stmt.setString(2, "callIndex");
stmt.execute();
Integer output = stmt.getInt(1);
System.out.println("outputValue is"+outputValue);
}
});
return outputValue;
}
}
But unfortunately this is giving me a different session factory than expected that is the connection string I am getting is of the other schema henceforth I am getting a bad sql exception.
Where I am going wrong on this?
So what you're saying is that getHibernateTemplate() returns a template with the wrong session factory? You're creating 2 session factories but not explicitly stating which one gets assigned to the EventDAOImpl instance.
#DependsOn only states that the object will be created by Spring after the ecommSessionFactory, that does not mean that it will be given that one.
See here
Beans on which the current bean depends. Any beans specified are guaranteed to be created by the container before this bean. Used infrequently in cases where a bean does not explicitly depend on another through properties or constructor arguments, but rather depends on the side effects of another bean's initialization.
May be used on any class directly or indirectly annotated with Component or on methods annotated with Bean.
I'd create the EventDAOImpl in my XML file and specify the SessionFactory bean that you want injected in the XML (either the ecommSessionFactory or the sessionFactory, I'm not sure which you want). Something like this:
<bean name="eventDAO" class=".....EventDaoImpl">
<property name="hibernateTemplate" ref="whicheverOneItShouldBe" />
How to inject EntityManager object using spring+JPA
I am using spring-context
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
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-2.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.javapapers.spring.mvc" />
<context:component-scan base-package="com.cnsi.dao.Impl" />
<mvc:annotation-driven />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- <jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/spitterPU"
/> -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#10.86.24.7:1521:wahipaaD" />
<property name="username" value="mddemo" />
<property name="password" value="mddemo" />
</bean>
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="ORACLE" />
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.OracleDialect" />
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/ spring-persistence.xml" />
<property name="persistenceUnitName" value="personPersistenceUnit" />
<property name="dataSource" ref="dataSource" />
<!-- <property name="jpaVendorAdapter" ref="jpaVendorAdapter" /> -->
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<!-- <bean class="com.cnsi.dao.Impl.JpaUserDao" id="jpaUserDao">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean> -->
</beans>
And my dao is, inject EntityManager
package com.cnsi.dao.Impl;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.cnsi.dao.UserDao;
import com.cnsi.modal.User;
#Repository
public class JpaUserDaoImpl implements UserDao {
#Autowired
EntityManagerFactory entityManagerFactory;
EntityManager em = entityManagerFactory.createEntityManager();
#Override
public void add(User u) {
em.persist(u);
}
#Override
public void edit(User u) {
em.merge(u);
}
#Override
public void delete(int id) {
em.remove(getInterfaceId(id));
}
#Override
public User getInterfaceId(int id) {
return (User) em.find(User.class, id);
}
#Override
public List<User> getAllInterface() {
return em.createQuery("from user").getResultList();
}
}
my persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
version="1.0">
<persistence-unit name="personPersistenceUnit" transaction-type="RESOURCE_LOCAL" >
<class>com.cnsi.modal.User</class>
</persistence-unit>
</persistence>
So I am getting below error:
java.lang.NoSuchMethodError: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.getJpaVendorAdapter()Lorg/springframework/orm/jpa/JpaVendorAdapter;
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:240)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:232)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFacto
#PersistenceContext
private EntityManager em;
That's how you inject entity manager in your controller.
I'm using Spring3.1, Hibernate(JPA) 4.1.2, GlassFish 3.1.2.
I have already successed to access to DB via JPA and JNDI datasource,
but when I tried to insert data to DB, met the problem below.
[#|2012-05-02T21:19:55.714+0900|WARNING|glassfish3.1.2|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=20;_ThreadName=Thread-2;|StandardWrapperValve[appServlet]: PWC1406: Servlet.service() for servlet appServlet threw exception
javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:976)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
at $Proxy227.flush(Unknown Source)
My source code is below.
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<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="persistenceUnit" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/myDataSource</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" />
<property name="hibernate.transaction.factory_class" value="org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory" />
</properties>
</persistence-unit>
</persistence>
Spring config
<context:annotation-config/>
<bean id="loadTimeWeaver" class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/myDataSource" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="persistenceUnit" />
<property name="loadTimeWeaver" ref="loadTimeWeaver" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
</property>
</bean>
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
<tx:annotation-driven transaction-manager="txManager"/>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="fooServiceOperation" expression="execution(* x.y.z.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation" />
</aop:config>
Dao interface
package x.y.z;
import org.springframework.transaction.annotation.Transactional;
public interface MyTableDao {
#Transactional
public void persist(MyTable myTable);
}
Dao implementation
package x.y.z;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
#Repository
public class MyTableDaoImpl implements MyTableDao {
#PersistenceContext
private EntityManager em;
public void persist(MyTable myTable) {
em.persist(myTable);
em.flush();
}
}
Please teach me what is wrong!
Place the #Transactional annotation on the concrete persist method instead of the interface.
I get this exception but I can not figure out what is wrong with my configuration
I am posting the relevent files thanks for any help
I am using
Spring 3.1.0.RELEASE
hibernate-entitymanager 3.6.10.Final (Should work with JPA 2)
Trying to run the code from a JUnit file
package com.successcharging.core.dao.jpa;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
import com.successcharging.core.security.dao.UserDao;
import com.successcharging.core.security.model.User;
import com.successcharging.core.security.model.UserImp;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {
"classpath:applicationContext/applicationContext*.xml"})
#TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true)
#Transactional
public class UserDaoImplTest {
private static final boolean ENABLED = true;
private static final String PASSWORD = "password";
private static final String USERNAME = "joe.bloggs";
#Autowired
private UserDao userDao;
private User user;
#Before
public void before() {
user = new UserImp();
user.setName(USERNAME);
user.setPassword(PASSWORD);
user.setEnabled(ENABLED);
userDao.save(user);
}
#Test
public void findByUserName() {
Assert.assertNotNull(user);
User user2 = userDao.findById(user.getId());
Assert.assertNotNull(user2);
Assert.assertEquals(USERNAME, user2.getName());
}
}
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"
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">
<context:annotation-config/>
<context:component-scan base-package="com.successcharging.core" />
</beans>
applicationContext-persistence.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">
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.successcharging.core" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLInnoDBDialect" />
</bean>
</property>
<property name="persistenceUnitName" value="successcharging.core.security" />
<property name="persistenceUnitManager">
<bean
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager" />
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.1.129:3306/SC_SECURITY" />
<property name="username" value="sc_admin" />
<property name="password" value="123" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven />
</beans>
persistence.xml
<?xml version="1.0" encoding="UTF-8" ?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="successcharging.core.security"
transaction-type="RESOURCE_LOCAL">
<properties>
<property name="cache.provider_class" value="org.hibernate.cache.NoCacheProvider" />
<property name="hibernate.max_fetch_depth" value="3" />
<property name="hibernate.query.factory_class"
value="org.hibernate.hql.classic.ClassicQueryTranslatorFactory" />
<property name="hibernate.query.substitutions" value="true 1, false 0" />
</properties>
</persistence-unit>
I found the problem I had to add the datasource to the persistenceUnitManager something like this
<property name="persistenceUnitManager">
<bean class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="defaultDataSource" ref="dataSource" />
</bean>
</property>
I was facing similar issue but was not using datasource in my case issue got resolved by adding hibernate key while providing database details in my persistence.xml file. Note that Hibernate 3.x and 4.x have different syntax as mentioned below (hit this while downgrading Hibernate 4.x to 3.x).
Changed below (Hibernate 4.x syntax) :
<properties>
<property name="javax.persistence.jdbc.driver" value="..."/>
<property name="javax.persistence.jdbc.url" value="..."/>
<property name="javax.persistence.jdbc.user" value="..."/>
<property name="javax.persistence.jdbc.password" value="..."/>
</properties>
With (Hibernate 3.x syntax) :
<properties>
<property name="hibernate.connection.driver_class" value="..."/>
<property name="hibernate.connection.url" value="..."/>
<property name="hibernate.connection.username" value="..."/>
<property name="hibernate.connection.password" value="..."/>
</properties>