My Dao layer has a save method as:
public void savePerson(PersonBean personBean) {
Session currentSession;
try {
currentSession = sessionFactory.getCurrentSession();
} catch (HibernateException e) {
currentSession = sessionFactory.openSession();
System.out.println("Opened Session");
}
currentSession.merge(personBean);
System.out.println("Data Saved");
}
And the applicationContext.xml is defined as :
<bean id="oracleDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url" value="jdbc:oracle:thin:#localhost:1521:{mylocalInstance}" />
<property name="username">
<value>PersonDataBase</value>
</property>
<property name="password">
<value>person</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="oracleDataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="mappingLocations" value="PersonBean.hbm.xml" />
</bean>
<bean id="testTransactional" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!--<tx:annotation-driven transaction-manager="testTransactional"/>-->
<bean id="personDao" class="com.dao.PersonDaoImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="personService" class="com.service.PersonServiceImpl">
<property name="personDao" ref="personDao"/>
</bean>
It is able to create the tables but the data is not saved, as I have to show the sql, this is the sql generated when trying to save:
INFO: Using DataSource [org.springframework.jdbc.datasource.DriverManagerDataSource#68be8808] of Hibernate SessionFactory for HibernateTransactionManager
Opened Session
Hibernate:
select
max(PERSON_ID)
from
PERSON_BEAN
Data Saved
Why is select query being generated when I am trying to save it.
You need to commit your transaction as well.
Try this:
public void savePerson(PersonBean personBean) {
Session currentSession;
try {
currentSession = sessionFactory.getCurrentSession();
} catch (HibernateException e) {
currentSession = sessionFactory.openSession();
System.out.println("Opened Session");
}
currentSession.beginTransaction();
currentSession.merge(personBean);
currentSession.getTransaction().commit()
System.out.println("Data Saved");
}
EDIT
You can also set hibernate.connection.autocommit property to true in Hibernate configuration if you don't want to handle transactions manually.
<property name="hibernate.connection.autocommit">true</property>
Try currentSession.save(personBean)
and if you properly configured the Spring then you don't need to
beginTransaction() Spring will handle the transaction .
public void savePerson(PersonBean personBean) {
Session currentSession;
try {
currentSession = sessionFactory.getCurrentSession();
} catch (HibernateException e) {
currentSession = sessionFactory.openSession();
System.out.println("Opened Session");
}
currentSession.beginTransaction();
currentSession.save(personBean);
currentSession.getTransaction().commit()
System.out.println("Data Saved");
}
Related
I have this in my servlet:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="12345" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.tricas.models" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
<prop key="hibernate.default_schema">test</prop>
<prop key="format_sql">true</prop>
<prop key="use_sql_comments">true</prop>
<!--<prop key="hibernate.hbm2ddl.auto">create</prop> -->
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
and my DaoImp
#Repository
#Transactional
public class UserDaoImp implements UserDao {
#Autowired
SessionFactory session;
public List<Users> list() {
return session.getCurrentSession().createQuery("from Users").list();
}
here is my HibernateUtil
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Log the exception.
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
And After executing the application I have a NullPointerException:
SEVERE [http-nio-8084-exec-97] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service () for servlet [spring-web] in context with path [/ Holaspringmvc] threw exception [Request processing failed; Nested exception is java.lang.NullPointerException] with root cause
Java.lang.NullPointerException
At com.tricas.dao.UserDaoImp.list (UserDaoImp.java:32)
Please help me.
Be simpler. Just declare SessionFactory bean
#Bean
public AbstractSessionFactoryBean sessionFactoryBean(){
AnnotationSessionFactoryBean sessionFactoryBean = new AnnotationSessionFactoryBean();
sessionFactoryBean.setConfigLocation(new ClassPathResource("hibernate.cfg.xml"));
return sessionFactoryBean;
}
similar for LocalSessionFactoryBean
btw: did you define component-scan ?
<context:component-scan base-package="<my.base.package>" />
I found the error, results that I had to define in the service and in the controller also with #Autowired
Here is my Service.
#Autowired
UserDao usrdao;
//private UserDao usrdao = new UserDaoImp();
#Transactional
public List<Users> getAllUsers() {
return usrdao.list();
}
and here is my controller
#Autowired
UserService usrv;
//private UserService usrv = new UserService();
#RequestMapping(value = "/verusuarios", method = RequestMethod.GET)
public String listPersons(Model model) {
List<Users> list = usrv.getAllUsers();
model.addAttribute("user", new Users());
model.addAttribute("list", list);
return "verusuarios";
}
Additionally I must add to guide me from this answer: answer here
Im creating a simple web app using Spring and Hibernate that has something to do with online shopping. My program is doing well when inserting new data using hibernate. When I check the db, the data is there. The problem is, the moment I fetch the new data I created, it gets nothing. I tried to put data in the db manually and hibernate gets the data. I'm sorry if this seems a beginner question, I'm studying Hibernate as a part of my training as a jr web developer. First, I wanna show you the config:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/------" />
<property name="username" value="----" />
<property name="password" value="------" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="packagesToScan" value="com.qbryx.domain" />
</bean>
Here is the code for adding a new product:
#Override
public void addProduct(Product product) {
Session session = sessionFactory.openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
Query query = session.createSQLQuery(DAOQuery.HQL_ADD_PRODUCT).setParameter("upc", product.getUpc())
.setParameter("category", product.getCategory().getCategoryId())
.setParameter("name", product.getName()).setParameter("description", product.getDescription())
.setParameter("price", product.getPrice());
query.executeUpdate();
transaction.commit();
} catch (HibernateException e) {
if (transaction != null)
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
#Override
public void addProductStock(InventoryProduct inventoryProduct) {
Session session = sessionFactory.openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
Query query = session.createSQLQuery(DAOQuery.HQL_ADD_PRODUCT_STOCK)
.setParameter("upc", inventoryProduct.getUpc())
.setParameter("stock", inventoryProduct.getStock());
query.executeUpdate();
transaction.commit();
} catch (HibernateException e) {
e.printStackTrace();
} finally {
session.close();
}
}
This code does fine with adding a new product together with the stock. Here is my code for fetching the product:
#Override
public InventoryProduct getInventoryProductByUpc(String upc) {
InventoryProduct product = null;
Session session = sessionFactory.openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
Query query = session.createQuery(DAOQuery.HQL_GET_INVENTORY_PRODUCT)
.setParameter("upc", upc);
product = (InventoryProduct) query.getSingleResult();
transaction.commit();
} catch (HibernateException e) {
if (transaction != null)
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
return product;
}
I don't understand why Hibernate can fetch data that is manually added to the database but not the data added through Hibernate. I need help. Thanks!
it's my first time I'm using hibernate so I've got a little question.
Is this way of using hibernate 5.1 with hikariCP 2.4.3 correct?
I'm not sure if the pooling is working like this.
should I call
Session session = sessionFactory.openSession();
or
Session session = sessionFactory.getCurrentSession();
to get a session?
when i call
session.close();
is the connection closed or given back to the pool.
the HibernateDataStore is used by threads for accessing the db
thanks for help
The Config
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.provider_class">
org.hibernate.hikaricp.internal.HikariCPConnectionProvider
</property>
<property name="hibernate.hikari.dataSourceClassName">
com.mysql.jdbc.jdbc2.optional.MysqlDataSource
</property>
<property name="hibernate.hikari.dataSource.url">
jdbc:mysql://localhost/xyz
</property>
<property name="hibernate.hikari.dataSource.user">user</property>
<property name="hibernate.hikari.dataSource.password">xyz</property>
<property name="hibernate.hikari.minimumIdle">20</property>
<property name="hibernate.hikari.maximumPoolSize">100</property>
<property name="hibernate.current_session_context_class">
org.hibernate.context.internal.ThreadLocalSessionContext
</property>
<!-- SQL dialect -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- Names the annotated entity class -->
<mapping class="XYZ"/>
</session-factory>
</hibernate-configuration>
My DataStore-Class
public class HibernateDataStore implements DataStore {
private static final Logger logger = LogManager.getLogger();
/** factory for hibernate sessions */
private static SessionFactory sessionFactory;
static {
setUpHibernate();
}
/**
* set up the hibernate session-factory
*/
private static void setUpHibernate() {
logger.debug("building session factory");
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure( "config/server/hibernate.cfg.xml" )
.build();
try {
sessionFactory = new MetadataSources( registry ).buildMetadata().buildSessionFactory();
}
catch (Exception e) {
logger.error("problems building hibernate sessionFactory " + e.getMessage());
// The registry would be destroyed by the SessionFactory, but we had trouble building the SessionFactory
// so destroy it manually.
StandardServiceRegistryBuilder.destroy( registry );
}
logger.debug("finished building session factory");
}
#Override
public void storeProduct(Product product) {
logger.info("storing product: " + product.getTitle());
Instant start = Instant.now();
final Session session = sessionFactory.openSession();
//final Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
session.save( product );
session.getTransaction().commit();
session.close();
Instant stop = Instant.now();
logger.debug("product saved (took " + Duration.between(start, stop).toMillis() + "ms)");
}
}
I think you should use Spring to handle session factory
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="springHikariCP" />
<property name="connectionTestQuery" value="SELECT 1" />
<property name="dataSourceClassName"
value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
<property name="dataSourceProperties">
<props>
<prop key="url">jdbc:mysql://localhost:3306/xyz</prop>
<prop key="user">root</prop>
<prop key="password"></prop>
</props>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="packagesToScan" value="com.xyz.model" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hikari.dataSource.minimumIdle">5</prop>
<prop key="hibernate.hikari.dataSource.maximumPoolSize">20</prop>
<prop key="hibernate.hikari.dataSource.idleTimeout">30000</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory">
</bean>
I am using spring 3.2 with hibernate 4. I want to use spring to control the transactions.
However with the configuration mentioned below I get the
'Servlet.service() for servlet spring threw exception: org.hibernate.HibernateException: No Session found for current thread'
exception:
<aop:config>
<aop:pointcut id="serviceMethods"
expression="execution(* com.locator.service.impl.ServiceTypeService.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="hbTransactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<!-- Hibernate session factory -->
<bean id="hbSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>../spring/model/ServiceType.hbm.xml</value>
</list>
</property>
</bean>
<bean id="hbTransactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="hbSessionFactory" />
</bean>
<bean id="serviceTypeService" class="com.locator.service.impl.ServiceTypeService">
<property name="serviceTypeDao" ref="serviceTypeDao"></property>
</bean>
<bean id="serviceTypeDao" class="com.locator.dao.impl.ServiceTypeDao">
<property name="sessionFactory" ref="hbSessionFactory"></property>
</bean>
The code for the Dao layer and the Service is as follows:
public class ServiceTypeDao implements IServiceTypeDao{
private static final Log log = LogFactory.getLog(ServiceTypeDao.class);
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory(){
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
public ServiceType findById(int id) {
log.debug("getting ServiceType instance with id: " + id);
try {
Session session = getSessionFactory().getCurrentSession();
ServiceType instance = (ServiceType) session.get("com.locator.model.ServiceType", id);
if (instance == null) {
log.debug("get successful, no instance found");
} else {
log.debug("get successful, instance found");
}
instance.setName(instance.getName()+"0");
session.saveOrUpdate(instance);
return instance;
}catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}
}
public class ServiceTypeService implements IServiceTypeService{
private ServiceTypeDao serviceTypeDao;
public void setServiceTypeDao(ServiceTypeDao serviceTypeDao){
this.serviceTypeDao = serviceTypeDao;
}
public ServiceType getServiceTypeById(int id){
return serviceTypeDao.findById(id);
}
}
Replacing getSessionFactory().getCurrentSession() with getSessionFactory().openSession() will resolve the above issue however, it will mean that the developer will then be responsible for the session open/close rather than spring. Therefore, please advise how this can be resolved using spring.
I was able to resolve the issue. It was occurring due to the following problems:
The Service class had not been Auto wired into the controller i.e. the #Autowired annotation was missing.
The configuration for the web.xml had to be modified with the listener class 'org.springframework.web.context.ContextLoaderListener' and the context-param was added.
I am using hibernate with spring frame work and my beans are in singleton mode.did i supposed to close my session or no (because they are in singleton mode)?
the reality is that we got some problems on our server and too many connections problem
and i thought may be that is the problem.thanks.
this is my codes:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" scope = "singleton" >
<property name="dataSource" ref local="dataSource" property/>
<property name="packagesToScan" >
<value>Model.Entity</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.auto_close_session">false</prop>
</props>
</property>
and this is the way i use , i close all sessions after i used
#Autowired
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void updateDB() {
Session session = getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
If you configure the spring and hibernate configuration you don't need to close the connections and sessions, Spring will do that for you.
See this example http://howtodoinjava.com/2013/03/21/spring-3-and-hibernate-integration-tutorial-with-example/