-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Deleting records problems caused by data inconsistency
PostPosted: Tue Jun 15, 2010 8:22 am 
Newbie

Joined: Mon Jun 14, 2010 3:04 pm
Posts: 1
Hello

This is the first time that I'm using Hibernate and I've been having a lot of troubles getting as far as I'm now. I managed to fix all the issues I had so far by scouring the hibernate manual and all forums imaginable.

I have the following scenario:

I have a small app in which you should be able to manage customers and their bills. A customer has a one-to-many relationship with bills and bills in his turn has a one-to-many relationship with rules (multiple rules can be defined for a specific bill). I think my major issue is getting the tables to update properly but I think it might be due to my mapping.

My maps are:

Client.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 package="nl.webresource.jf.hibernate.model">
<class name="Client" table="Clients">
    <id name="ClientID" column="ClientID" type="int">
        <generator class="increment"></generator>
    </id>
    <property name="FirstName" column="FirstName" type="string"></property>
    <property name="SurName" column="SurName" type="string"></property>
    <property name="CompanyName" column="CompanyName" type="string"></property>
    <property name="Street" column="Street" type="string"></property>
    <property name="HouseNumber" column="HouseNumber" type="int"></property>
    <property name="HouseNumberAddition" column="HouseNumberAddition" type="string"></property>
    <property name="PostalCode" column="PostalCode" type="int"></property>
    <property name="City" column="City" type="string"></property>
    <property name="VatNR" column="VatNR" type="string"></property>
    <property name="EmailAddress" column="EmailAddress" type="string"></property>
    <property name="PhoneNumber" column="PhoneNumber" type="string"></property>
    <property name="MobileNumber" column="MobileNumber" type="string"></property>
    <property name="Inactive" column="Inactive" type="boolean"></property>
       
    <list name="bills" table="Bills" inverse="true" lazy="false" fetch="subselect" cascade="all">
        <key column="ClientID" not-null="true" update="false" />
        <index column="BillID"/>
        <one-to-many class="nl.webresource.jf.hibernate.model.Bill" />
    </list>
</class>
</hibernate-mapping>


Bills.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 package="nl.webresource.jf.hibernate.model">
<class name="Bill" table="Bills">
    <id name="BillID" column="BillID" type="int">
        <generator class="increment"></generator>
    </id>
    <property name="ClientID" column="ClientID" type="int"></property>
    <property name="BillDate" column="BillDate" type="date"></property>
    <property name="Paid" column="Paid" type="boolean"></property>
   
    <list name="rules" table="Rules" inverse="true" cascade="all,delete-orphan">
        <key column="BillID" update="false" />
        <list-index column="Position" />
        <one-to-many class="nl.webresource.jf.hibernate.model.Rule" />
    </list>
</class>
</hibernate-mapping>


Rule.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 package="nl.webresource.jf.hibernate.model">
<class name="Rule" table="Rules">
    <id name="RuleID" column="RuleID" type="int">
        <generator class="increment"></generator>
    </id>
   
    <property name="Name" column="Name" type="string"></property>
    <property name="Price" column="Price" type="double"></property> 
</class>
</hibernate-mapping>


I am using Dao's to insert/edit/delete records. I have a Dao for each table and they all implement abstractDao.

AbstractDao.java
Code:
public abstract class AbstractDao {
    private Session session;
    private Transaction tx;

    public AbstractDao() {
       try {
          HibernateFactory.buildIfNeeded();
       } catch(Exception e) {
          System.out.println(e.getMessage());
       }
    }

    protected void saveOrUpdate(Object obj) {
        try {
            startOperation();
            session.saveOrUpdate(obj);
            tx.commit();
        } catch (HibernateException e) {
            handleException(e);
        } finally {
            HibernateFactory.close(session);
        }
    }

    protected void delete(Object obj) {
        try {
            startOperation();
            session.delete(obj);
            tx.commit();
        } catch (HibernateException e) {
            handleException(e);
        } finally {
            HibernateFactory.close(session);
        }
    }

    protected Object find(Class clazz, int i) {
        Object obj = null;
        try {
            startOperation();
            obj = session.load(clazz, i);
            tx.commit();
        } catch (HibernateException e) {
            handleException(e);
      } finally {
            //HibernateFactory.close(session);
        }
        return obj;
    }

    protected List findAll(Class clazz) {
        List objects = null;
        try {
            startOperation();
            Query query = session.createQuery("from " + clazz.getName());
            objects = query.list();
            tx.commit();
        } catch (HibernateException e) {
            handleException(e);
        } finally {
            HibernateFactory.close(session);
        }
        return objects;
    }
   
    protected List findAll(Class clazz, String condition) {
        List objects = null;
        try {
            startOperation();
            Query query = session.createQuery("from " + clazz.getName() + condition);
            objects = query.list();
            Hibernate.initialize(objects);
            tx.commit();
        } catch (HibernateException e) {
            handleException(e);
        } finally {
            HibernateFactory.close(session);
        }
        return objects;
    }
   
    protected void findbla(Class clazz) {
       HibernateFactory.sessionFactory.getClassMetadata(clazz).getPropertyNames();
    }

    protected void handleException(HibernateException e) throws DataAccessLayerException {
        HibernateFactory.rollback(tx);
        throw new DataAccessLayerException(e);
    }

    protected void startOperation() throws HibernateException {
        session = HibernateFactory.openSession();
        tx = session.beginTransaction();
    }
}


All other Dao.java files are the same except for the arguments
Code:
package nl.webresource.jf.hibernate.dao;

import nl.webresource.jf.hibernate.model.Client;

import java.util.List;

public class ClientDao extends AbstractDao {
    public ClientDao() {
        super();
    }

    /**
     * Insert a new Client into the database.
     * @param event
     */
    public void create(Client client) throws DataAccessLayerException {
        super.saveOrUpdate(client);
    }


    /**
     * Delete a detached Client from the database.
     * @param client
     */
    public void delete(Client client) throws DataAccessLayerException {
        super.delete(client);
    }

    /**
     * Find an Client by its primary key.
     * @param i
     * @return
     */
    public Client find(int i) throws DataAccessLayerException {
        return (Client) super.find(Client.class, i);
    }

    /**
     * Updates the state of a detached Client.
     *
     * @param client
     */
    public void update(Client client) throws DataAccessLayerException {
        super.saveOrUpdate(client);
    }

    /**
     * Finds all Clients in the database.
     * @return
     */
    public List findAll() throws DataAccessLayerException{
        return super.findAll(Client.class);
    }
   
    public List findAll(String condition) throws DataAccessLayerException{
        return super.findAll(Client.class, condition);
    }

}


So far I've got everything to work except deleting a client just after adding a bill! I think my problem started with the mapping of the list. At first I was using lazy="true" but that threw the LazyInitializationException when I tried to use the getBills().size() function on one of the clients. After digging through the manual I changed the lazy="false" and started using that in combination with fetch="subselect". That worked pretty well until I added about 5+ clients. It slowed everything down so I figured that wasn't the way to go..

Basically I am trying to get the following scenario:
Whenever I add a bill it should (somehow) update the entry in the Client table so that when I try to delete the client immediatly after adding a bill it would correctly fetch the amount of bills a certain user has (through c.getBills().size()). I tried removing the client from the tablemodel's list and then adding it again but that ended up with 2 of the same records for that client. For some reason it wasn't deleting it properly. Maybe because the client instance changed due to the new bill being added..

I was hoping that someone could point me in the right direction because my hands are pretty tied right now and I've been trying to get this to work for a few days now... I've tried so many different mapping settings but none seem to give the correct effect.

I was thinking about the following scenario:

When a user is set for deletion (toolbar button) it should first check if that user has any Bills in the system. If that's true the user should be set to inactive by defining the Inactive column to true. That part does the trick! However if I have both tables open and I try to add a bill and then immediatly switch tabs without reloading the application, upon deletion of the Client it says there are 0 bills.. Thus it deletes the client. That is ofcourse not what is suppose to happen. I am quite sure that it is due to data inconsistency because the Client instance in the Clients JTable doesn't get updated correctly..

Hopefully I've made myself a bit clear. If I have missed any source code please let me know so I can post it.

Thanks in advance!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.