[PJUG Javamail] Problem with hibernate
Michael Phoenix
michaelandrewphoenix at gmail.com
Fri Sep 18 14:34:58 EDT 2009
Sean,
Thanks so much for your kind response. Even though I managed to
resolve the problem through a much simpler change, your response is a
good teaching moment as I continue to learn all the ins and outs of
hibernate and JSF.
I managed to resolve the problem by changing the load method in my DAO
to a get method. I was thinking about making that change anyway as get
does not throw exceptions if you don';t find the object matching the
identifier. It was quite a surprise to find that using load was the
source of my problem. I am definitely not initializing the proxy from
the JSF. All hibernate processing is taking place in the DAO in order
to separate the data access from the Web app logic. From what you are
telling me you need to do to get hibernate to work from a Web app, I
think that is a good strategy.
On Fri, Sep 18, 2009 at 12:39 PM, Sean Adkinson <sean.adkinson at gmail.com> wrote:
> Hi Michael,
>
> That error doesn't necessarily mean that there isn't a session, it just
> means that there isn't a session associated with that HibernateProxy object
> (in your case, the User). This can happen if you hold a lazy-loaded object
> around after a transaction is committed or the session is closed.
>
> For example, let's say that Person objects have a lazy loaded Emails
> association.
>
> session.beginTransaction();
> Person p = dao.getPerson();
> session.commitTransaction();
> p.getEmails(); <--- lazy initialization fail
>
> Now I don't see exactly how this is happening given your code below, but you
> say it is happening in your JSF page. Sometimes transactions are committed
> after Actions run, before beginning to parse the JSF, so if that is the
> case, trying to initialize the proxy from the JSF would cause this error.
>
> A few ways we solved this problem:
>
> 1) Configure sessions with hibernate to have long conversations, so that the
> session isn't flushed on transaction commit. You can do this by using a
> custom extension of ThreadLocalSessionContext that only flushes manually,
> and setting it as the hibernate.current_session_context_class property.
> Note that this will mean that you need to control the session flushing on
> your own, and should flush after all processing is done.
>
> 2) Have an open transaction around JSF processing. Maybe use a
> ServletFilter that starts and stops transactions/sessions between entire
> requests.
>
> 3) Given a "detached" object (one that has no session associated with it and
> will throw a LazyInitializatioException if a lazy-loaded property is
> accessed), "reattach" the object to the current session. In our
> HibernateUtil, we have the following method:
>
> public void attachObjectToCurrentSession(Object object)
> {
> getSession().lock(object, LockMode.NONE);
> }
>
>
> Let me know if any of this helps!
>
> - Sean
>
>
>
> On Fri, Sep 18, 2009 at 10:19 AM, Michael Phoenix
> <michaelandrewphoenix at gmail.com> wrote:
>>
>> I'm having a problem with lazy fetching and accessing data through
>> hibernate from my JSF Web app. I am using a DAO pattern to access my
>> data through Hibernate. At first, it woriked fine and would pass all
>> my unit tests. When I tried to access it though my Web bean LogonBean,
>> it does not return any data into the User object I initialize, but
>> doesn't give me any data. I have double-checked the mysql database
>> table and the record with the key I am using is definitely there. When
>> I ran junit tests again, I started getting this exception in the find
>> method:
>>
>> Code:
>> org.hibernate.LazyInitializationException <init>
>> SEVERE: could not initialize proxy - no Session
>>
>>
>> I cannot understand why it cannot find the session as the session is
>> being created just before the load. I did a debug on it and it appears
>> the session is there when the load is executed. The other DAO methods
>> run fine. There is a lot written on lazy fetching and mixed reviews on
>> turning it off. I'm not sure I can even do that in this simple
>> database. Suggestions on what the problem might be and how to resolve
>> it would be greatly appreciated.
>>
>> I'm using Hibernate 3, MySQL 5.0, and NetBeans 6.7.1
>>
>> hibernate-cfg.xml
>> Code:
>> <?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.dialect">org.hibernate.dialect.MySQLDialect</property>
>> <property
>> name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
>> <property
>> name="hibernate.connection.url">jdbc:mysql://localhost:3306/quoteestimator</property>
>> <property name="hibernate.connection.username">root</property>
>> <property name="hibernate.connection.password">dilbert</property>
>> <mapping resource="user.hbm.xml"/>
>> </session-factory>
>> </hibernate-configuration>
>>
>>
>> user.hbm.xml
>> Code:
>> <?xml version="1.0" encoding="UTF-8"?>
>> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD
>> 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
>>
>> <hibernate-mapping>
>> <class name="com.lingosys.hibernate.quoteest.User" table="users">
>> <id name="id" type="string">
>> <generator class="assigned"/>
>> </id>
>> <property name="name" type="string"/>
>> <property name="password" type="string"/>
>> <property name="admin" type="char"/>
>> </class>
>> </hibernate-mapping>
>>
>>
>> UserDao.java
>> Code:
>> /*
>> * To change this template, choose Tools | Templates
>> * and open the template in the editor.
>> */
>>
>> package com.lingosys.hibernate.quoteest;
>>
>> /**
>> *
>> * @author mphoenix
>> */
>> import org.hibernate.HibernateException;
>> import org.hibernate.Session;
>> import org.hibernate.Transaction;
>> import org.hibernate.Query;
>> import java.util.List;
>>
>> /**
>> * The Data Access Object for managing the persistent Users.
>> *
>> */
>> public class UserDao {
>> private Session session;
>> private Transaction tx;
>>
>> public UserDao() {
>> HibernateFactory.buildIfNeeded();
>> }
>>
>> /**
>> * Insert a new User into the database.
>> * @param User
>> */
>> public void create(User User) throws DAOException {
>> try {
>> startOperation();
>> session.save(User);
>> tx.commit();
>> } catch (HibernateException e) {
>> handleException(e);
>> } finally {
>> HibernateFactory.close(session);
>> }
>> }
>>
>>
>> /**
>> * Delete a detached User from the database.
>> * @param user
>> */
>> public void delete(User user) throws DAOException {
>> try {
>> startOperation();
>> session.delete(user);
>> tx.commit();
>> } catch (HibernateException e) {
>> handleException(e);
>> } finally {
>> HibernateFactory.close(session);
>> }
>> }
>> /**
>> * Find an User by its primary key.
>> * @param id
>> * @return
>> */
>> public User find(String id) throws DAOException {
>> User user = null;
>> try {
>> startOperation();
>> user = (User) session.load(User.class, id);
>> tx.commit();
>> } catch (HibernateException e) {
>> handleException(e);
>> } finally {
>> HibernateFactory.close(session);
>> }
>> return user;
>> }
>>
>> /**
>> * Updates the state of a detached User.
>> *
>> * @param User
>> */
>> public void update(User User) throws DAOException {
>> try {
>> startOperation();
>> session.update(User);
>> tx.commit();
>> } catch (HibernateException e) {
>> handleException(e);
>> } finally {
>> HibernateFactory.close(session);
>> }
>> }
>>
>> /**
>> * Finds all Users in the database.
>> * @return
>> */
>> public List findAll() throws DAOException{
>> List users = null;
>> try {
>> startOperation();
>> Query query = session.createQuery("from User");
>> users = query.list();
>> tx.commit();
>> } catch (HibernateException e) {
>> handleException(e);
>> } finally {
>> HibernateFactory.close(session);
>> }
>> return users;
>> }
>>
>> private void handleException(HibernateException e) throws DAOException
>> {
>> HibernateFactory.rollback(tx);
>> throw new DAOException(e);
>> }
>>
>> private void startOperation() throws HibernateException {
>> session = HibernateFactory.openSession();
>> tx = session.beginTransaction();
>> }
>>
>> }
>>
>>
>> HibernateFactory.java
>> Code:
>> package com.lingosys.hibernate.quoteest;
>>
>> import org.hibernate.*;
>> import org.hibernate.cfg.Configuration;
>>
>> public class HibernateFactory {
>> private static SessionFactory sessionFactory;
>>
>> /**
>> * Constructs a new Singleton SessionFactory
>> * @return
>> * @throws HibernateException
>> */
>> public static SessionFactory buildSessionFactory() throws
>> HibernateException {
>> if (sessionFactory != null) {
>> closeFactory();
>> }
>> return configureSessionFactory();
>> }
>>
>> /**
>> * Builds a SessionFactory, if it hasn't been already.
>> */
>> public static SessionFactory buildIfNeeded() throws DAOException{
>> if (sessionFactory != null) {
>> return sessionFactory;
>> }
>> try {
>> return configureSessionFactory();
>> } catch (HibernateException e) {
>> throw new DAOException(e);
>> }
>> }
>> public static SessionFactory getSessionFactory() {
>> return sessionFactory;
>> }
>>
>>
>> public static Session openSession() throws HibernateException {
>> buildIfNeeded();
>> return sessionFactory.openSession();
>> }
>>
>> public static void closeFactory() {
>> if (sessionFactory != null) {
>> try {
>> sessionFactory.close();
>> } catch (HibernateException ignored) {
>> System.out.println("Couldn't close SessionFactory" +
>> ignored);
>> }
>> }
>> }
>>
>> public static void close(Session session) {
>> if (session != null) {
>> try {
>> session.close();
>> } catch (HibernateException ignored) {
>> System.out.println("Couldn't close Session" + ignored);
>> }
>> }
>> }
>>
>> public static void rollback(Transaction tx) {
>> try {
>> if (tx != null) {
>> tx.rollback();
>> }
>> } catch (HibernateException ignored) {
>> System.out.println("Couldn't rollback Transaction" + ignored);
>> }
>> }
>> /**
>> *
>> * @return
>> * @throws HibernateException
>> */
>> private static SessionFactory configureSessionFactory() throws
>> HibernateException {
>> Configuration configuration = new Configuration();
>> configuration.configure();
>> sessionFactory = configuration.buildSessionFactory();
>> return sessionFactory;
>> }
>> }
>>
>>
>> LogonBean.java (authenticate method only)
>> Code:
>> public String authenticate() throws NoSuchAlgorithmException,
>> NoSuchAlgorithmException, UnsupportedEncodingException {
>> UserDao dao = new UserDao();
>> String id = getUid();
>> User user = dao.find(id);
>> PasswordProcessor pp = PasswordProcessor.getInstance();
>> if (pp.encrypt(getPassword()).equals(user.getPassword())) {
>> setAuthenticated(true);
>> if (user.getAdmin() == 'Y')
>> setAdmin(true);
>> return "loggedon";
>> }
>> else {
>> // FacesContext.getCurrentInstance().
>> // addMessage(null, new FacesMessage("Incorrect
>> user ID and/or password, please try again."));
>> return "failed";
>> }
>>
>> }
>>
>>
>> Junit test code
>> Code:
>> @Test
>> public void testCreate() {
>> System.out.println("create");
>> User user = new User("testing", "Phoenix, Michael", "pass", 'Y');
>> UserDao instance = new UserDao();
>> instance.create(user);
>> }
>>
>> @Test
>> public void testFind() {
>> System.out.println("find");
>> String id = "testing";
>> UserDao instance = new UserDao();
>> User result = instance.find(id);
>> System.out.println("name = " + result.getName());
>> System.out.println("password = " + result.getPassword());
>> }
>>
>> @Test
>> public void testUpdate() {
>> System.out.println("update");
>> User User = new User("testing", "Phoenix, M", "nopass", 'Y');
>> UserDao instance = new UserDao();
>> instance.update(User);
>> }
>>
>> @Test
>> public void testFindAll() {
>> System.out.println("findAll");
>> UserDao instance = new UserDao();
>> List result = instance.findAll();
>> Iterator iter = result.iterator();
>> while (iter.hasNext()) {
>> User user = (User) iter.next();
>> System.out.println("name = " + user.getName());
>> System.out.println("password = " + user.getPassword());
>> }
>> }
>>
>> @Test
>> public void testDelete() {
>> System.out.println("delete");
>> User user = new User("testing", "Phoenix, M", "nopass", 'Y');
>> UserDao instance = new UserDao();
>> instance.delete(user);
>> }
>> _______________________________________________
>> Web Site - http://www.pjug.org/
>> Javamail mailing list
>> Javamail at pjug.org
>> http://www.pjug.org/mailman/listinfo/javamail
>
>
>
> --
> Sean Adkinson
> (503) 731-5488 work, (503) 866-0852 cell
> sean.adkinson at gmail.com
>
More information about the Javamail
mailing list