0

I am using PrimeFaces 3.5, JSF 2.2, Hibernate 4.1, Spring 3.2.3, MySQL in my application. Function updateUser() is supposed to update record in the database for the selected user from the PrimeFaces dataTable component(values are correct) but for some unknown reason it doesn't. I have a class named AbstractDAO which implements CRUD operations via generics. Insertion, selection and deleting works perfectly, but update fails without showing any errors at all. Any clues what can be wrong in my code?


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:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:sec="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">


    <!--            GLOABL SETTINGS             -->


    <context:component-scan base-package="com.infostroy.adminportal"/>
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>


    <!--        DATA SOURCE AND PERSISTENCE SETTINGS       -->


    <bean id="propertiesPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:db.properties</value>
            </list>
        </property>
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dmDataSource"/>
        <property name="packagesToScan" value="com.infostroy.adminportal"/>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${db.dialect}</prop>
                <prop key="hibernate.show_sql">${db.show_sql}</prop>
                <prop key="hibernate.hbm2ddl.auto">${db.hbm2ddl_auto}</prop>
                <prop key="connection.pool_size">${db.pool_size}</prop>
                <prop key="current_session_context_class">${db.current_session_context_class}</prop>
                <prop key="org.hibernate.FlushMode">${db.flush_mode}</prop>
            </props>
        </property>
    </bean>


    <bean id="transactionManager"
          class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="dataSource" ref="dmDataSource" />
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>


    <bean id="dmDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${db.driver}" />
        <property name="url" value="${db.url}" />
        <property name="username" value="${db.username}" />
        <property name="password" value="${db.password}" />
        <property name="maxWait" value="5000" />
        <property name="initialSize" value="2" />
        <property name="maxActive" value="100"/>
        <property name="maxIdle" value="50"/>
        <property name="minIdle" value="0"/>
    </bean>

</beans>

db.properties:

db.username=root
db.password=root
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost/adminportal
db.pool_size=0
db.dialect=org.hibernate.dialect.MySQLDialect
db.hbm2ddl_auto=validate
db.show_sql=true
db.current_session_context_class=thread
db.flush_mode=COMMIT

AbstractDAO:

public abstract class AbstractDAO<T extends Serializable> implements Serializable {

@Autowired
protected SessionFactory sessionFactory;
protected T object;
protected Class clazz;

public AbstractDAO(Class clazz) {
    this.clazz = clazz;
}

//Executes before being removed from container
@PreDestroy
protected void destroy() {
    sessionFactory.getCurrentSession().close();
}

public Session getHiberSession() {
    return sessionFactory.openSession();
}

@Transactional
protected T getByID(int id) {
    String queryString = "from " + clazz.getSimpleName() + " where id = :id";
    Query query = getHiberSession().createQuery(queryString);
    query.setInteger("id", id);
    object = (T) query.uniqueResult();
    return object;
}

@Transactional
protected int deleteByID(int id) {
    String queryString = "delete " + clazz.getSimpleName() + " where id = :id";
    Query query = getHiberSession().createQuery(queryString);
    query.setInteger("id", id);
    return query.executeUpdate();
}

@Transactional
protected boolean insert(T object) {
    try {
        getHiberSession().save(object);
        return true;
    } catch (HibernateException ex) {
        return false;
    }
}

@Transactional
protected boolean update(T object) {
    try {
        getHiberSession().saveOrUpdate(object);
        return true;
    } catch (HibernateException ex) {
        return false;
    }
}

@Transactional
protected List getAllRecords() {
    String queryString = "from " + clazz.getSimpleName();
    Query query = getHiberSession().createQuery(queryString);
    return query.list();
}

}

UserDAO.java:

@Repository
public class UserDAO extends AbstractDAO<User> {

public UserDAO() {
    super(User.class);
}

public User getUserById(int id) {
    return super.getByID(id);
}

public int deleteUserById(int id) {
    return super.deleteByID(id);
}

public boolean insertUser(User user) {
    return super.insert(user);
}

public boolean updateUser(User user) {
    return super.update(user);
}

public List<User> getAllUsers() {
    return super.getAllRecords();
}
}

If you need any additional info or code - just tell me. Every answer is highly appreciated and responded immidiately.

Thank you.

4
  • I'm just starting with Hibernate, but I'm using sessionFactory.getCurrentSession() instead of openSession(). Commented Jan 28, 2014 at 17:39
  • OMG, replacing openSession with getCurrentSession worked! :D The other question is why the hell it works for other functions? Please, post your response as answer so I could accept it. Commented Jan 28, 2014 at 17:47
  • When you use transactions managed by Spring(@TRansactional) the framework gets a session and starts a transaction before th method and commits it after that. When you getCurrentSession you use the same session(and transaction) and it's OK, but openSession() gets onother session, which is not commited. Just a guess. Commented Jan 28, 2014 at 18:19
  • This makes sense now. Commented Jan 28, 2014 at 18:24

2 Answers 2

3

I'm just starting with Hibernate, but I'm using sessionFactory.getCurrentSession() instead of openSession().

Sign up to request clarification or add additional context in comments.

Comments

1

After saveOrUpdate() mehod just flush the session. Ex: session.flush();

For more details you can see my blog here:

http://www.onlinetutorialspoint.com/hibernate/hibernate-example.html

1 Comment

Session is flushed implicitly during commit and managed declaratively by Spring so there's no point in managing sessions, transactions and flushing. Even if I explicitly make my function call flush after saveOrUpdate statement - it doesn't fix the problem. The solution was to call existing session instead of creating a new one. Still, thank you for your contribution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.