jsf - Hibernate - Caching Probleme

alan79

Mitglied
Hallo Forum

Ich habe seit längerem mit Hibernate Caching Problemen in einer JSF Applikation zu kämpfen. Es sieht so aus als würden manchmal Datenänderung erst verzögert in die Datenbank geschrieben d.h. nach einem Update navigiere ich auf eine andere Seite (mit redirect). Es wird mir der alte Zustand des Datensatzes angezeigt. (auch in der Datenbank ist die Änderung noch nicht ersichtlich. Erst nach einer erneute Navigation wird die Änderung in die DB geschrieben.

Ich habe schon diverses probiert. Ich nehme an es hängt irgendwie mit dem HibernateFilter zusammen. Vielleicht hat ja jemand bereits ähnlich Erfahrungen gemacht und hat mir einen Tipp.

Ich nutze fogldene Frameworks:
MyFaces 1.2.6
Facelets 1.1.14
richfaces 3.3.1
hibernate 3.3.1

HibernateFilter:
Code:
package com.xxx.groupware.hibernate;

import static com.xxx.groupware.hibernate.HibernateUtil.closeSession;
import static com.xxx.groupware.hibernate.HibernateUtil.commitTransaction;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.log4j.Logger;


/**
 * A servlet filter that opens and closes a Hibernate Session for each request.
 * <p>
 * This filter guarantees a sane state, committing any pending database
 * transaction once all other filters (and servlets) have executed. It also
 * guarantees that the Hibernate <tt>Session</tt> of the current thread will
 * be closed before the response is send to the client.
 * <p>
 * Use this filter for the <b>session-per-request</b> pattern and if you are
 * using <i>Detached Objects</i>.
 *
 * @see HibernateUtil
 * @author Christian Bauer <christian@hibernate.org>
 */
public class HibernateFilter implements Filter {

	private static Logger log = Logger.getLogger(HibernateFilter.class);

    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("Servlet filter init, now opening/closing a Session for each request.");
    }

    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain)
            throws IOException, ServletException {

        try {
             // We don't start the database transaction here, but when first needed

              
        	chain.doFilter(request, response);

            // Commit any pending database transaction.
        	
        	commitTransaction();

        } finally {

            // No matter what happens, close the Session.

                   	
        	closeSession();


        }
    }

    public void destroy() {}

}

HibernateUtil:
Code:
package com.xxx.groupware.hibernate;

import org.apache.log4j.Logger;
import org.hibernate.CacheMode;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

/**
 * Basic Hibernate helper class, handles SessionFactory, Session and Transaction.
 * <p>
 * Uses a static initializer for the initial SessionFactory creation
 * and holds Session and Transactions in thread local variables.
 *
 * @author christian@hibernate.org
 */
public class HibernateUtil {

	private static Logger log = Logger.getLogger(HibernateUtil.class);

    private static Configuration configuration;
    private static SessionFactory sessionFactory;
    private static final ThreadLocal threadSession = new ThreadLocal();
    private static final ThreadLocal threadTransaction = new ThreadLocal();


    // Create the initial SessionFactory from the default configuration files
    
    static {
		try {
			log.info("Start building Session Factory..");
			configuration = new Configuration();
			sessionFactory = configuration.configure().buildSessionFactory();
			// We could also let Hibernate bind it to JNDI:
			// configuration.configure().buildSessionFactory()
			log.info("Building Session Factory succeeded..");
		} catch (Throwable ex) {
			// We have to catch Throwable, otherwise we will miss
			// NoClassDefFoundError and other subclasses of Error
			log.error("Building SessionFactory failed.", ex);
			throw new ExceptionInInitializerError(ex);
		}
	}
	

    /**
	 * Returns the SessionFactory used for this static class.
	 *
	 * @return SessionFactory
	 */
    public static SessionFactory getSessionFactory() {
        
    	/* Instead of a static variable, use JNDI:
        SessionFactory sessions = null;
        try {
			log.info("Start building Session Factory..");
			configuration = new Configuration();
			sessionFactory = configuration.configure().buildSessionFactory();
			log.info("Building Session Factory succeeded..");
		} catch (Throwable ex) {
			log.error("Building SessionFactory failed.", ex);
			throw new ExceptionInInitializerError(ex);
		}
        return sessions;
        */
    	return sessionFactory;
        
    }

    /**
     * Retrieves the current Session local to the thread.
     * <p/>
     * If no Session is open, opens a new Session for the running thread.
     *
     * @return Session
     */
    public static Session getSession() {
         // With CMT, this should return getSessionFactory().getCurrentSession() and do nothing else
        Session s = (Session) threadSession.get();
       //System.out.println("***DEBUG - session init - session: "+s);
       if (s!=null){
    	   //System.out.println("***DEBUG - session init - session: open? "+s.isOpen());
    	   s.isOpen();
       }
        // added isOpen to condition to make it possible to close a session for detached objects...
        if (s == null || !s.isOpen()) {
            log.debug("Opening new Session for this thread.");
            SessionFactory sFactory = getSessionFactory(); 
            //System.out.println("***DEBUG - session init - session null! try get factory: "+sFactory);
            if (sFactory==null){
            	log.error("Building SessionFactory failed.");
    			
            }
            else
            {
            	s=sFactory.openSession();
            	//System.out.println("***DEBUG - session init - session after getting factory: open? "+s.isOpen());
            }
           threadSession.set(s);
        }
        //s.setCacheMode(CacheMode.REFRESH);
        return s;
    }

    /**
     * Closes the Session local to the thread.
     */
    public static void closeSession() {
              // Would be written as a no-op in an EJB container with CMT
            Session s = (Session) threadSession.get();
            threadSession.set(null);
            if (s != null && s.isOpen()) {
                log.debug("Closing Session of this thread.");
                s.flush();
                s.close();
                System.out.println("Session has been flushed and closed...");
            }
    }

    /**
     * Start a new database transaction.
     */
    public static void beginTransaction() {
          // Would be written as a no-op in an EJB container with CMT
        Transaction tx = (Transaction) threadTransaction.get();
            if (tx == null) {
                log.debug("Starting new database transaction in this thread.");
                tx = getSession().beginTransaction();
                threadTransaction.set(tx);
            }
    }

    /**
     * Commit the database transaction.
     */
    public static void commitTransaction() {
          // Would be written as a no-op in an EJB container with CMT
        Transaction tx = (Transaction) threadTransaction.get();
        try {
            if ( tx != null && !tx.wasCommitted()
                            && !tx.wasRolledBack() ) {
                log.debug("Committing database transaction of this thread.");
                tx.commit();
            }
            //threadTransaction.set(null);
        } catch (HibernateException ex) {
            rollbackTransaction();
            throw ex;
        }
    }

    /**
     * Rollback the database transaction.
     */
    public static void rollbackTransaction() {
          // Would be written as a no-op in an EJB container with CMT (maybe setRollBackOnly...)
        Transaction tx = (Transaction) threadTransaction.get();
        try {
            threadTransaction.set(null);
            if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() ) {
                log.debug("Tyring to rollback database transaction of this thread.");
                tx.rollback();
            }
        } finally {
            closeSession();
        }
    }

}

Hibernate-CFG:
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.bytecode.use_reflection_optimizer">false</property>
        <property name="hibernate.connection.autocommit">true</property>
        <property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
        <property name="hibernate.connection.password">xxxxxx</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost/timerep</property>
        <property name="hibernate.connection.username">xxxx</property>
        <property name="hibernate.default_catalog">timerep</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
        <property name="hibernate.show_sql">false</property>
        <property name="hibernate.autoReconnect">true</property>
        <mapping ......
    </session-factory>
</hibernate-configuration>

Viele Dank für irgendwelche Hinweise.
Grüsse
Alan
 
Zuletzt bearbeitet:
Ich habe das Ganze nochmals genauer unter die Lupe genommen. Es scheint weniger das Problem zu sein, dass die Änderung verzögert in der DB vollzogen wird sondern eher dass Hibernate das Objekt noch irgendwie in einem alten Zustand im Cache hat.

Es verhält sich so:

1. Page mit Datensatzliste
2. Click auf Datensatz -> Navigation zu Detailsansicht (ohne redirect)
3. Änderung des Datensatzes -> Navigation zu Datensatzliste (mit redirect)
4. Datenänderung in Datensatzliste nicht ersichtlich (aber in der DB schon)
5. Verlassen der Seite (navigation zu Hauptseite)
6. Erneutes Anzeigen der Datensatzliste -> Änderung ist ersichtlich

Hat jemand mit ähnlichem Verhalten bereits zu kämpfen gehabt?

Danke für irgendwelche Tipps.
Grüsse
Alan
 
Die Frage ist halt, wie du mit der Session bzw. Transaktionen umgehst. Um Daten wirklich in der DB zu haben musst du entweder die Session schließen oder ein Flush machen... d.h. so ein wenig Datenzugriffscode zu sehen wär schon was cooles...

REINHAUN!
 
Hallo Oliver

Ich liefere gerne noch einwenig Code dazu

Ich nutze eine Klasse Dao, die die generellen Transaktions funktionen zur Verfügung stellt:
Code:
package com.antavis.groupware.dao;

import static com.antavis.groupware.hibernate.HibernateUtil.commitTransaction;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.hibernate.Hibernate;

import com.antavis.groupware.hibernate.HibernateUtil;


public class Dao {

	public Dao() {
		HibernateUtil.beginTransaction();
	}
	

	public Integer add(Object o) {
		Integer id = (Integer) HibernateUtil.getSession().save(o);
		HibernateUtil.commitTransaction();
		HibernateUtil.getSession().flush();
		return id;
	}
	public void commit(){
		HibernateUtil.commitTransaction();
	}
	public void saveOrUpdate(Object o) {
		HibernateUtil.getSession().saveOrUpdate(o);
		HibernateUtil.commitTransaction();
		HibernateUtil.getSession().flush();
	}
	public void merge(Object o) {
		
		HibernateUtil.getSession().merge(o);
		HibernateUtil.commitTransaction();
		HibernateUtil.getSession().flush();
		
			
	}
	public void persist(Object o){
		HibernateUtil.getSession().persist(o);
		//HibernateUtil.commitTransaction();
	}

	public void delete(Object o) {
		HibernateUtil.getSession().delete(o);
		//HibernateUtil.commitTransaction();
	}
	
	public void delete(Object o, Boolean flush) {
		HibernateUtil.getSession().delete(o);
		
		if (flush==true)
		HibernateUtil.getSession().flush();
		
		//HibernateUtil.commitTransaction();
		
	}

	public void initialize(Object o) {
		Hibernate.initialize(o);
	}
	
	public ResultSet executeQueryNativeSQL(String sqlQuery){
		
		Connection con;
	    Statement stmt;
	    ResultSet rs=null;
		
		try {
            Class.forName( "com.mysql.jdbc.Driver" );
        }
        catch ( ClassNotFoundException e ) {
            e.printStackTrace();
        }

        try {
            con = DriverManager.getConnection("jdbc:mysql://localhost/timerep","timerep","Whoop123" );
            stmt = con.createStatement();
            rs = stmt.executeQuery(sqlQuery);
            }
        catch ( SQLException e ){
         e.printStackTrace();
        }
        finally{
        	
        }
			
		return rs;
		
	}
	public Boolean executeUpdateNativeSQL(String sql){
		Connection con;
	    Statement stmt;
	    Boolean retVal=false;
	    try {
            Class.forName( "com.mysql.jdbc.Driver" );
        }
        catch ( ClassNotFoundException e ) {
            e.printStackTrace();
        }

        try {
            con = DriverManager.getConnection("jdbc:mysql://localhost/timerep","timerep","Whoop123" );
            stmt = con.createStatement();
            stmt.executeUpdate(sql);
            commitTransaction();
            retVal=true;
            }
        catch ( SQLException e ){
         e.printStackTrace();
        }
   
			
		return retVal;
		
	}


}

ProjectDao - Stellt modul spezifische DB Funktionen zur Verfügung:
Code:
package com.antavis.groupware.dao;

import static com.antavis.groupware.hibernate.HibernateUtil.commitTransaction;
import static com.antavis.groupware.hibernate.HibernateUtil.getSession;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.Session;

import com.antavis.groupware.hibernate.HibernateUtil;
import com.antavis.groupware.model.Contacts;
import com.antavis.groupware.model.Projectroles;
import com.antavis.groupware.model.Projects;
import com.antavis.groupware.model.ProjectsRoles;
import com.antavis.groupware.model.UserProjects;
import com.antavis.groupware.model.Users;
import com.antavis.groupware.model.Workpackages;

public class ProjectDao implements ProjectEventRegistry{
	private Dao dao = new Dao();

	public ProjectDao(){
		HibernateUtil.beginTransaction();
	}

	public Integer add(Projects project) {
		int i = dao.add(project);
		return i;
	}
	public Integer add(UserProjects uProject) {
		int i = dao.add(uProject);
		return i;
	}
	
	public Integer add(ProjectsRoles pRoles) {
		int i = dao.add(pRoles);
		return i;
	}
	public Integer add(Workpackages wPackage) {
		int i = dao.add(wPackage);
		return i;
	}
	public void delete(Workpackages wPackage) {
		Session session = HibernateUtil.getSession();
		wPackage = (Workpackages)session.merge(wPackage);

		dao.delete(wPackage, true);
		
		
		
	}
	
	public void refresh(Projects project){
		Session session = HibernateUtil.getSession();
		session.refresh(project);
		
		
		
	}

	public void commit() {
		HibernateUtil.commitTransaction();

	}

	public void delete(Projects project) {
		dao.delete(project);

	}

	public ArrayList<Projects> getList() {
		String hqlQuery="FROM Projects AS project order by project.company.companyId, project.projectName";
		Session session = getSession();
		
		session.beginTransaction();
		ArrayList records = (ArrayList) session.createQuery(hqlQuery)
		.list();
		commitTransaction();
		return records;
	}
	
	public ArrayList<Projects> getList(Boolean active) {
		String hqlQuery="FROM Projects AS project where project.active=? and order by project.company.companyId, project.projectName";
		Session session = getSession();
		session.beginTransaction();
		ArrayList records = (ArrayList) session.createQuery(hqlQuery)
		.setBoolean(0, active)
		.list();
		commitTransaction();
		return records;
	}
	public ArrayList<Projects> getListProjectsForResponsible(int contactId) {
		String hqlQuery="FROM Projects AS project where project.contactsByResponsibleId.contactId=? and project.active=? order by project.projectName";
		Session session = getSession();
		session.beginTransaction();
		ArrayList records = (ArrayList) session.createQuery(hqlQuery)
		.setInteger(0, contactId)
		.setBoolean(1,true)
		.list();
		commitTransaction();
		return records;
	}
	
	public ArrayList<Workpackages> getProjectPackages(int projectId) {
		String hqlQuery="FROM Workpackages AS package where package.projects.projectId=? order by package.packageReference";
		Session session = getSession();
		session.beginTransaction();
		ArrayList records = (ArrayList) session.createQuery(hqlQuery)
		.setInteger(0, projectId)
		.list();
		commitTransaction();
		return records;
	}
	
	public ArrayList<Workpackages> getProjectPackages(int projectId, Boolean active) {
		String hqlQuery="FROM Workpackages AS package where package.projects.projectId=? and package.active=? order by package.packageReference";
		Session session = getSession();
		session.beginTransaction();
		ArrayList records = (ArrayList) session.createQuery(hqlQuery)
		.setInteger(0, projectId)
		.setBoolean(1, active)
		.list();
		commitTransaction();
		return records;
	}
	
	public ArrayList<Projectroles> getListRolesAll() {
		String hqlQuery="FROM Projectroles AS role order by role.roleName";
		Session session = getSession();
		session.beginTransaction();
		ArrayList records = (ArrayList) session.createQuery(hqlQuery)
		.list();
		commitTransaction();
		return records;
	}
	
	public Projectroles getRoleByRoleName(String roleName) {
		Session session = getSession();
		session.beginTransaction();
		String hqlQuery="FROM Projectroles AS role where role.roleName='"+roleName+"'";
		ArrayList roles = (ArrayList) session.createQuery(hqlQuery).list();
		Projectroles role = (Projectroles)roles.get(0);
		
		commitTransaction();
		return role;
	}
	
	public ProjectsRoles getProjectRoleByRoleName(String roleName, int projectId) {
		Session session = getSession();
		session.beginTransaction();
		String hqlQuery="FROM ProjectsRoles AS roles where roles.projects.projectId=? and roles.projectroles.roleName=?";
		ArrayList roles = (ArrayList) session.createQuery(hqlQuery)
		.setInteger(0, projectId)
		.setString(1, roleName)
		.list();
		ProjectsRoles role = (ProjectsRoles)roles.get(0);
		
		commitTransaction();
		return role;
	}
	
	
	public Projectroles getDefaultRole(int projectId, int userId) {
		Session session = getSession();
		session.beginTransaction();
		String hqlQuery="FROM UserProjects AS uProjects where uProjects.projects.projectId=? and uProjects.users.userId=?";
		ArrayList userProjects = (ArrayList) session.createQuery(hqlQuery)
		.setInteger(0, projectId)
		.setInteger(1, userId)
		.list();
		UserProjects uProjects = (UserProjects)userProjects.get(0);
		
		commitTransaction();
		return uProjects.getProjectroles();
	}
	
	public ArrayList<Projects> getAvailableProjects(int userId) {
		String hqlQuery="select project FROM Projects AS project left join project.userProjectses as users where project.active=? and users.users.userId=? order by project.company.companyId, project.projectName";
		Session session = getSession();
		session.beginTransaction();
		ArrayList records = (ArrayList) session.createQuery(hqlQuery)
		.setBoolean(0, true)
		.setInteger(1, userId)
		.list();
		commitTransaction();
		return records;
	}
	
	public ArrayList<Projects> getUsersProjects(int userId) {
		String hqlQuery="select project FROM Projects AS project left join project.userProjectses as users where users.users.userId=? order by project.company.companyId, project.projectName";
		Session session = getSession();
		session.beginTransaction();
		ArrayList records = (ArrayList) session.createQuery(hqlQuery)
		.setInteger(0, userId)
		.list();
		commitTransaction();
		return records;
	}
	
	public ArrayList<ProjectsRoles> getProjectsRoles(int projectId) {
		String hqlQuery="FROM ProjectsRoles AS roles where roles.projects.projectId=? order by roles.projectroles.roleName";
		Session session = getSession();
		session.beginTransaction();
		ArrayList records = (ArrayList) session.createQuery(hqlQuery)
		.setInteger(0, projectId)
		.list();
		commitTransaction();
		return records;
	}
	
	public void deleteUserProjects(Projects project) {
		String hql = "delete from UserProjects as uprojects where uprojects.projects.projectId=?";
		Session session = getSession();
		session.beginTransaction();
		Query query = session.createQuery(hql);
        query.setInteger(0, project.getProjectId());
        int rowCount = query.executeUpdate();
		
		
		
		HibernateUtil.commitTransaction();
		HibernateUtil.getSession().flush();
	}
	
	public void deleteProjectRoles(Projects project) {
		String hql = "delete from ProjectsRoles as proles where proles.projects.projectId=?";
		Session session = getSession();
		session.beginTransaction();
		Query query = session.createQuery(hql);
        query.setInteger(0, project.getProjectId());
        int rowCount = query.executeUpdate();
		
		
        HibernateUtil.commitTransaction();
		HibernateUtil.getSession().flush();
		
	}

	public Projects getProjectsById(int projectId) {
		Session session = HibernateUtil.getSession();
		session.beginTransaction();
		Projects rec = (Projects)session.load(Projects.class, projectId);

		session.getTransaction().commit();
		return rec;
	}

	public void update(Projects project) {
		Session session = HibernateUtil.getSession();
		//System.out.println("*** DEBUG ** DAO - SAVE PROJECT: Customer Contacts: "+project.getContactsByCustomerId());
		dao.merge(project);
		commit();
		//commit();
		//HibernateUtil.getSession().persist(project);
		//session.getTransaction().commit();
		//session.flush();
		//HibernateUtil.commitTransaction();
		

	}
	public void update(UserProjects uProject) {
		//System.out.println("*** DEBUG ** DAO - SAVE PROJECT: Customer Contacts: "+project.getContactsByCustomerId());
		dao.merge(uProject);
		commit();

	}
	public void update(Workpackages wPackage) {
		//System.out.println("*** DEBUG ** DAO - SAVE PROJECT: Customer Contacts: "+project.getContactsByCustomerId());
		dao.merge(wPackage);
		commit();
		

	}
	public void saveOrUpdate(Projects project){
		dao.saveOrUpdate(project);
	}
	public void saveOrUpdate(UserProjects uProject){
		dao.saveOrUpdate(uProject);
	}
	public void persist(Projects project){
		dao.persist(project);
	}

	public ArrayList<Contacts> getProjectUsers(Projects project) {
		ArrayList<Contacts> projectUsers = new ArrayList();
		Set <UserProjects> userProjects = project.getUserProjectses(); 


		Iterator it = userProjects.iterator();
		while (it.hasNext()) {
			UserProjects uProject = (UserProjects)it.next();
			Users user =  uProject.getUsers();

			Set <Contacts> contacts = user.getContactses();
			Iterator it2 = contacts.iterator();
			Contacts contact = (Contacts)it2.next();

			projectUsers.add(contact);
		}


		return projectUsers;

	}

	public ArrayList<String> getProjectUsersList(Projects project) {
		ArrayList<String> projectUsers = new ArrayList<String>();
		Set <UserProjects> userProjects = project.getUserProjectses(); 
		System.out.println("*** DEBUG Project Users: userprojects found: "+userProjects.size());

		Iterator it = userProjects.iterator();
		while (it.hasNext()) {
			UserProjects uProject = (UserProjects)it.next();
			Users user =  uProject.getUsers();
			System.out.println("*** DEBUG Project Users: user found: "+user.getLoginName());

			projectUsers.add(user.getLoginName());
		}


		return projectUsers;

	}
}

Auszug ProjectHandler (Request bean)
Code:
public class ProjectHandler implements GwsHandler {

	private ResourceBundle msg;
	private ProjectValidator validator = new ProjectValidator();
	private SuggestionSupport sugSup = new SuggestionSupport();
	
	private List<Projects> allProjects;
	
	private Projects projectRecord;
	
	private Workpackages editPackage;
	private Workpackages createPackage;
	private Boolean showPackageDetailsEdit;
	private Boolean showPackageDetailsCreate;
	private Boolean deletePackageAvailable=false;
	private ProjectDao dao = new ProjectDao();
	private String noRecords;
	private String noRecordsPackages;
	private HtmlDataTable dataTable;
	private HtmlDataTable dataTablePackages;
	private List<Workpackages> projectPackages;
	private Double totalWpackageMoney;
	private Double totalWpackageMoneyLeft;
	private Double totalWpackageHours;
	private Double totalWpackageHoursLeft;
	private static Logger log = Logger.getLogger(ProjectHandler.class);
	ArrayList<SelectItem>packageTypes=new ArrayList<SelectItem>();
	private HtmlPanelGrid actionBar = new HtmlPanelGrid();

	private ArrayList<Contacts> responsibleList = new ArrayList<Contacts>();
	private String projectResponsible = "";


	private ArrayList<Company> companyList = new ArrayList<Company>();
	private String projectCompany = "";

	private ArrayList<Contacts> contactList = new ArrayList<Contacts>();
	private String projectContact = "";
	

	private ArrayList <UserProject>projectUsersSrcPickList=new ArrayList<UserProject>();
	private List <UserProject>projectUsersTrgtPickList = new ArrayList<UserProject>();
	

	private ArrayList <ProjectRole>projectRolesSrcPickList=new ArrayList<ProjectRole>();
	private List <ProjectRole>projectRolesTrgtPickList = new ArrayList<ProjectRole>();
	

	private ArrayList<SelectItem> projectRoleNames = new ArrayList<SelectItem>();



	private List <Users>allUsers;
	private List <Projectroles>allRoles;

	public ProjectHandler(){
		super();
		
		System.out.println("******** DEBUG - PROJECTHANDLER HAS BEEN INITIATED...");

		msg = new MiscUtil().getMessageBundle();

		this.projectRecord=new Projects();
		this.allProjects=dao.getList();
		

		if (allProjects.isEmpty()){
			noRecords = msg.getString("listNoRecordFound");
		}

		responsibleList=new ContactsDao().getListGWUsers();
		


		companyList=new CompanyDao().getList(true);
		

		this.allUsers=new UserDao().getList(true);
		for (int i=0;i<allUsers.size();i++){
			Users user = allUsers.get(i);
			UserProject uProject = new UserProject();
			uProject.setLoginName(user.getLoginName());
			this.projectUsersSrcPickList.add(uProject);
		}

		this.allRoles=new ProjectDao().getListRolesAll();
		for (int i=0;i<allRoles.size();i++){
			Projectroles role = allRoles.get(i);
			ProjectRole pRole = new ProjectRole();
			pRole.setRoleName(role.getRoleName());
			pRole.setRateHour(new Double("0"));
			pRole.setMaxHoursPerDay(new Double("0"));
			pRole.setMaxRateDay(new Double("0.0"));
			this.projectRolesSrcPickList.add(pRole);

			projectRoleNames.add(new SelectItem(pRole.getRoleName()));
		}

		Collections.sort(projectUsersSrcPickList);
		Collections.sort(projectRolesSrcPickList);
		
		ArrayList<ListValues>lValues = new ListValueDao().getList("packageType");
		for (ListValues val : lValues){
			packageTypes.add(new SelectItem(val.getValue()));
		}
		actionBar=new ActionBar().generateActionBar(true, true, false, false, "projectHandler");
		


	}

	public String cancelModify(){
				
		return "cancel";
	}
	
	public String deleteRecord(){
		
		return "not implemented";
	}
	public String editRecord(){
		actionBar=new ActionBar().generateActionBar(true, false, true, false, "projectHandler");
		this.projectUsersSrcPickList.clear();
		this.projectUsersTrgtPickList.clear();
		this.projectRolesSrcPickList.clear();
		this.projectRolesTrgtPickList.clear();
		projectRecord = (Projects) dataTable.getRowData();
		//dao.refresh(projectRecord);
		initProjectPackages(projectRecord);

		Set <ProjectsRoles>projectRoles=projectRecord.getProjectsRoleses();
		Iterator<ProjectsRoles> iteratorRoles = projectRoles.iterator();

		while (iteratorRoles.hasNext()) {
			ProjectsRoles elem = ((ProjectsRoles) iteratorRoles.next());
			ProjectRole pRole = new ProjectRole();
			pRole.setRoleName(elem.getProjectroles().getRoleName());
			pRole.setMaxHoursPerDay(elem.getMaxHoursPerDay());
			pRole.setRateHour(elem.getRateHour());
			pRole.setMaxRateDay(elem.getMaxRateDay());

			this.projectRolesTrgtPickList.add(pRole);
		}


		for (int i=0;i<this.allRoles.size();i++){
			Projectroles role = allRoles.get(i);
			Boolean exists = false;
			for (int i2=0;i2<this.projectRolesTrgtPickList.size();i2++){

				if (this.projectRolesTrgtPickList.get(i2).getRoleName().equals(role.getRoleName())){
					exists=true;
					break;
				}
			}

			if (exists==false){

				ProjectRole pRole = new ProjectRole();
				pRole.setRoleName(role.getRoleName());
				pRole.setRateHour(new Double("0"));
				pRole.setMaxHoursPerDay(new Double("0"));
				pRole.setMaxRateDay(new Double("0.0"));
				this.projectRolesSrcPickList.add(pRole);
			}
		}


		Set <UserProjects>projectUsers=projectRecord.getUserProjectses();


		Iterator<UserProjects> iterator = projectUsers.iterator();

		while (iterator.hasNext()) {
			UserProjects elem = ((UserProjects) iterator.next());
			UserProject uProject = new UserProject();

			uProject.setLoginName(elem.getUsers().getLoginName());
			uProject.setDefaultRole(elem.getProjectroles().getRoleName());

			this.projectUsersTrgtPickList.add(uProject);
		}

		for (int i=0;i<this.allUsers.size();i++){
			Users user = allUsers.get(i);
			Boolean exists = false;
			for (int i2=0;i2<this.projectUsersTrgtPickList.size();i2++){
				if (this.projectUsersTrgtPickList.get(i2).getLoginName().equals(user.getLoginName())){
					exists=true;
					break;
				}
			}
			if (exists==false){
				UserProject uProject = new UserProject();
				uProject.setLoginName(user.getLoginName());
				//SelectItem item = new SelectItem(uProject,user.getLoginName());
				//item.setValue(role.getRoleName());
				this.projectUsersSrcPickList.add(uProject);
			}
		}

		Collections.sort(projectUsersTrgtPickList);
		Collections.sort(projectUsersSrcPickList);
		Collections.sort(projectRolesTrgtPickList);
		Collections.sort(projectRolesSrcPickList);
		/*
		Collections.sort(editProjectUsersTrgtPickList, new Comparator<UserProject>() {

	        public int compare(UserProject p1, UserProject p2) {
	        	if (p1.getLoginName().compareTo(p2.getLoginName())>0)
	    			return 1;
	        	if (p1.getLoginName().compareTo(p2.getLoginName())<0)
	    			return -1;
	    		return 0;	        }
	    });
		 */


		projectResponsible=projectRecord.getContactsByResponsibleId().getFirstName()+" "+projectRecord.getContactsByResponsibleId().getLastName();

		projectCompany=projectRecord.getCompany().getName();

		projectContact = projectRecord.getContactsByCustomerId().getFirstName()+" "+projectRecord.getContactsByCustomerId().getLastName();


		return "goToProjectEdit";
	}
	
	public Boolean validateRecord(){
		return validator.validateRecord(projectRecord);
	}

	public String saveRecord(){

		if (projectResponsible==null || projectResponsible.equals("") )
			projectRecord.setContactsByResponsibleId(null);

		if (projectCompany==null || projectCompany.equals(""))
			projectRecord.setCompany(null);

		if (projectContact==null || projectContact.equals(""))
			projectRecord.setContactsByCustomerId(null);

				
		Boolean valid = validateRecord();

		if (valid==false)
			return "validationFailure";
		
		valid=true;
		valid = validator.validateRecord(projectRolesTrgtPickList, projectUsersTrgtPickList);
		if (valid==false)
			return "validationFailure";


		dao.deleteUserProjects(projectRecord);
		dao.deleteProjectRoles(projectRecord);
		Set <ProjectsRoles>pRoles=new HashSet();
		for (int i=0;i<projectRolesTrgtPickList.size();i++){
			ProjectRole role = projectRolesTrgtPickList.get(i);
			ProjectsRoles pRole = new ProjectsRoles();
			pRole.setProjectroles(new ProjectDao().getRoleByRoleName(role.getRoleName()));
			pRole.setMaxHoursPerDay(role.getMaxHoursPerDay());
			pRole.setRateHour(role.getRateHour());
			pRole.setMaxRateDay(role.getMaxRateDay());
			pRole.setProjects(projectRecord);
			pRole.setProjects(projectRecord);
			int id = dao.add(pRole);

			pRole.setProjectsRolesId(id);
			pRoles.add(pRole);

		}




		Set <UserProjects>userProjects=new HashSet();
		for (int i=0;i<projectUsersTrgtPickList.size();i++){
			UserProject userProject = projectUsersTrgtPickList.get(i);
			UserProjects uProject = new UserProjects();
			uProject.setUsers(new UserDao().getUserByLoginName(userProject.getLoginName()));
			uProject.setProjects(projectRecord);
			uProject.setProjectroles(new ProjectDao().getRoleByRoleName(userProject.getDefaultRole()));

			//userProject.setRateDayMax(new Double("0"));
			//userProject.setRateHours(new Double("0"));

			int id = dao.add(uProject);

			uProject.setUserProjectKey(id);
			userProjects.add(uProject);
		}
		projectRecord.setUserProjectses(userProjects);
		
		// Reassign packages - since the may have been modified (deleted)
		ArrayList<Workpackages> wPackages=dao.getProjectPackages(projectRecord.getProjectId());
		Set <Workpackages>projectPackages=new HashSet();
		for (Workpackages p : wPackages){
			
			projectPackages.add(p);
		}
		projectRecord.setWorkpackageses(projectPackages);


		dao.update(projectRecord);
		dao.commit();



		//this.allProjects=dao.getList();
		
		return "success";

	}



}

- Die Funktion "ProjectHandler.editRecord" selektiert den Record von der Liste und zeigt die Detail page an (ohne redirect).
- Die Funktion "ProjectHandler.saveRecord" speichert den Record und führt per redirect zurück auf die Datensatzliste.

Hier noch die web.xml:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
	xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<display-name>groupware</display-name>

	<!-- FACELET CONFIGURATION -->
	<context-param>
		<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
		<param-value>.xhtml</param-value>
	</context-param>

	
	<context-param>
                <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
                <param-value>server</param-value>
        </context-param>
        <!-- disable compression of state in server -->
        <context-param>
                <param-name>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</param-name>
                <param-value>true</param-value>
        </context-param>
        <!-- Very important, too, is to disable the serialization of state,
          serialization and deserialization of the component tree is a major performance hit. -->
        <context-param>
                <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
                <param-value>true</param-value>
        </context-param>
        <!-- If you find that memory is a constraining factor, then reducing the number of views stored in the session might help -->
        <context-param>
            <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION </param-name>
            <param-value>0</param-value>
        </context-param>


	<context-param>
		<param-name>facelets.LIBRARIES</param-name>
		<param-value>
			/WEB-INF/facelets/taglibs/converter.taglib.xml
		</param-value>
	</context-param>


	<!-- RICHFACES CONFIGURATION - START -->
	<context-param>
		<param-name>org.richfaces.SKIN</param-name>
		<param-value>blueSky</param-value>
	</context-param>

	<filter>
		<display-name>RichFaces Filter</display-name>
		<filter-name>richfaces</filter-name>
		<filter-class>org.ajax4jsf.Filter</filter-class>
		<!--  should optimize performance  -->
		<init-param>
			<param-name>forceparser</param-name>
			<param-value>false</param-value>
		</init-param>

	</filter>

	<!--  GLOBAL AJAX Event QUEUE -->
	<context-param>
		<param-name>org.richfaces.queue.global.enabled</param-name>
		<param-value>true</param-value>
	</context-param>

	<!--
		the following neko xml parser should be faster than the standard one
	-->
	<context-param>
		<param-name>org.ajax4jsf.xmlparser.ORDER</param-name>
		<param-value>NEKO</param-value>
	</context-param>

	<context-param>
		<param-name>org.ajax4jsf.xmlparser.NEKO</param-name>
		<param-value>.*\..*</param-value>
	</context-param>


	<filter-mapping>
		<filter-name>richfaces</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- RICHFACES CONFIGURATION - END -->

	<!--
		TAGLIB FOR APACHE TOMAHAWK WITH FACLETS <context-param>
		<param-name>facelets.LIBRARIES</param-name>
		<param-value>/WEB-INF/tomahawk.taglib.xml</param-value>
		</context-param>
	-->

	<servlet>
		<servlet-name>groupware-servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>groupware-servlet</servlet-name>
		<url-pattern>/faces/*</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>groupware-servlet</servlet-name>
		<url-pattern>*.jsf</url-pattern>
	</servlet-mapping>




	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	<session-config>
		<session-timeout>90</session-timeout>
	</session-config>


	<!--
		HIBERNATE FILTER START - Filter disabled - not needed If used
		database transactions do not work...
	-->
	<filter>
		<filter-name>HibernateFilter</filter-name>
		<filter-class>com.antavis.groupware.hibernate.HibernateFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>HibernateFilter</filter-name>
		<url-pattern>*.jsf</url-pattern>
	</filter-mapping>
	<!-- HIBERNATE FILTER END -->

	<!-- TOMAHAWK SETTINGS START -->
	<filter>
		<filter-name>MyFacesExtensionsFilter</filter-name>
		<filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
		<init-param>
			<param-name>maxFileSize</param-name>
			<param-value>20m</param-value>
		</init-param>
	</filter>

	<!--
		extension mapping for adding <script/>, <link/>, and other resource
		tags to JSF-pages
	-->
	<filter-mapping>
		<filter-name>MyFacesExtensionsFilter</filter-name>
		<!--
			servlet-name must match the name of your
			javax.faces.webapp.FacesServlet entry
		-->
		<servlet-name>groupware-servlet</servlet-name>
	</filter-mapping>

	<!--
		extension mapping for serving page-independent resources (javascript,
		stylesheets, images, etc.)
	-->
	<filter-mapping>
		<filter-name>MyFacesExtensionsFilter</filter-name>
		<url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
	</filter-mapping>

	<!-- TOMAHAWK SETTINGS END -->



	<security-constraint>
		<web-resource-collection>
			<web-resource-name>Geschuetzter Bereich</web-resource-name>
			<url-pattern>/pages/*</url-pattern>
		</web-resource-collection>
		<auth-constraint>
			<role-name>user</role-name>
		</auth-constraint>
	</security-constraint>
	<login-config>
		<auth-method>FORM</auth-method>
		<form-login-config>
			<form-login-page>/login.jsp</form-login-page>
			<form-error-page>/error.jsp</form-error-page>
		</form-login-config>
	</login-config>
	<security-role>
		<role-name>user</role-name>
	</security-role>
</web-app>

Das interessante ist, dass in anderen Bereichen der Applikation alles wunderbar funktioniert, obwohl der genau gleiche Code für den Save verwendet wird. Möglicherweise hat das was mit dem relativ komplexen Save des Projects zu tun (aufgrund Beziehungen zu anderen Tabellen wie z.B. ProjectRoles, Workpackages etc.)?

Falls du noch was anderes sehen möchtest melde dich bitte.
Vielen Dank für deine Hilfe!
Grüsse
Alan
 
Zuletzt bearbeitet:
Wow, schon lang keinen so schlechte Code mehr gesehen. Ich frag mich grad wie ihr da nur einen einzigen test dafür schreibt? Ne Transaktion an nen Objektlebenszyklus zu hängen halte ich für eine sehr schlechte Idee. Wer macht eigentlich die Session wieder zu, die du durch beginTransaction() implizit aufmachst? Mit plain JDBC irgendwo zwischen HIbernate queries rumzupfuschen - großes Kino... zu mal das Resourcehandling da - sagen wir es gelinde - nicht vorhanden ist. Preisfrage: was passiert mit Statement und Connection wenn bei rs = stmt.executeQuery(sqlQuery); (aus Dao (das den namen nicht wirklich verdient) executeQueryNativeSQL(String sqlQuery)) eine Exception fliegt? Letzte Frage: ich würde vom vielen STRG+C, STRG+V aka. Copy & Paste schon längst ne Sehnenscheidenentzündung haben... stört euch das nicht selbst?

Kurz: der "Code" da ist so voller Bugnester, dass da hinter jeder Ecke das nächste Disaster lauert. Das offenbart sich nach einem kurzen Überfliegen. Wie du da Fehler finden willst, ist mir schleierhaft...

Sorry, wenn ichs so verreis, aber wie soll da jemand reinsteigen? Bzw. noch anders: warum sollte sich jemand externes das antun, zu versuchen da durchzusteigen, wenn nicht mal die elementarsten Grundlagen beachtet wurden.

Gruß
Ollie
 
Hallo Oliver

Schon ok. Ist sicher mühsam ständig Post's von dummen Anfängern wie mir zu beantworten.

Du musst wissen ich programmiere Java nebenberuflich und versuche mir das alles selbst beizubrigen. Und bin auch schon ziemlich weit gekommen unterdessen. Das Ganze ist doch ziemlich komplex und wenn man da zu Beginn ein Konzept noch nicht 100%ig verstanden hat oder etwas nicht ganz ideal einsetzt ist das aus meiner Sicht verständlich. Mir ist absolut bewusst, dass ich noch viel zu lernen hab.

Folgende Methoden in der Klasse Dao, die den Namen nicht verdient hat, werden nicht verwendet (das war bloss mal ein Versuch. sorry, hätte ich aufräumen müssen vor dem Paste).:
- executeUpdateNativeSQL
- executeQueryNativeSQL
d.h. es werden nur die Basis Aktionen verwendet:
- add
- saveOrUpdate
- merge
- delete
Welche, soweit ich Anfänger das Verstanden hab, dem Konzept von Hibernate entsprechen.

Das ProjectDao stellt dann die Project spezifischen Dao Funktionen zur Verfügung:
z.B.
- getList (-> Liste aller Projekte)
- getAvailableProjects(int userId) (-> Liste der Projekte, die einem bestimmten user zur Verfügung stehen)
- add, update, delete -> welche dann die Methoden in der Basis Dao aufrufen

Bezüglich des impliziten Aufrufs von beginTransaction() nehme ich an du meinst dies hier:
Code:
public ArrayList<Projects> getList() {
		String hqlQuery="FROM Projects AS project order by project.company.companyId, project.projectName";
		Session session = getSession();
		
		session.beginTransaction();
		ArrayList records = (ArrayList) session.createQuery(hqlQuery)
		.list();
		commitTransaction();
		return records;
	}

Ich nehme an so wäre es besser?
Code:
public ArrayList<Projects> getList() {
		String hqlQuery="FROM Projects AS project order by project.company.companyId, project.projectName";
		Session session = getSession();
		
		//session.beginTransaction();
		ArrayList records = (ArrayList) session.createQuery(hqlQuery)
		.list();
		commitTransaction();
		return records;
	}

Vielen Dank für den Hinweis! Das behebt dann auch gleich die Probleme mit der Datensatzliste welche nicht die aktuellen Daten anzeigt..

Ich weiss nun jedoch auch wieder wieso ich die beginTransaction() eingebaut hab:
Code:
SCHWERWIEGEND: Servlet.service() for servlet default threw exception
javax.el.ELException: /pages/projects/popup_project_report.xhtml @25,83 createContent="#{projectReportHandler.generateStatusChartForProject}": org.hibernate.TransactionException: Transaction not successfully started
	at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:74)
	at org.ajax4jsf.resource.UserResource.send(UserResource.java:110)
	at org.ajax4jsf.resource.ResourceLifecycle.sendResource(ResourceLifecycle.java:215)
	at org.ajax4jsf.resource.ResourceLifecycle.send(ResourceLifecycle.java:144)
	at org.ajax4jsf.resource.InternetResourceService.serviceResource(InternetResourceService.java:226)
	at org.ajax4jsf.resource.InternetResourceService.serviceResource(InternetResourceService.java:141)
	at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:488)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
	at java.lang.Thread.run(Thread.java:619)
Caused by: org.hibernate.TransactionException: Transaction not successfully started
	at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:131)
	at com.antavis.groupware.dao.ProjectDao.getProjectsById(ProjectDao.java:247)
	at com.antavis.groupware.handler.ProjectReportHandler.generateStatusChartForProject(ProjectReportHandler.java:64)
	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.apache.el.parser.AstValue.invoke(AstValue.java:172)
	at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
	at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68)
	... 19 more
Der Fehler wird durch folgende Komponente verursacht:
Code:
<a4j:mediaOutput element="img" cacheable="false" session="true"
								createContent="#{projectReportHandler.generateStatusChartForProject}"
								value="#{projectHandler.projectRecord.projectId}" mimeType="image/jpeg" />
Hier wird ein Chart generiert und zu diesem Zeitpunkt scheint irgendwie keine Transaktion zur Verfügung zu stehen. Daraufhin hab ich das mit dem impliziten beginTransaction() probiert und das hat den Fehler behoben. Leider war mir die Auswirkung dessen nicht bewusst. Hast du mir diesbezüglich einen Tip?

Falls du gar keine Lust mehr hast Dir das überhaupt weiter anzuschauen danke ich dir das du dir überhaupt Zeit genommen hast kurz reinzuschauen..

Gruss
Alan

----------------------------------------------------------
PS:
Von wegen Copy & Paste - Mir ist absolut klar, dass ich bestimmt noch was lernen kann im Objektorientierten Programmieren. Du musst wissen, dass ist meine erste Java Webapplication und leider sitzt mir kein Guru zur Seite der mich auf Fehler hinweist. Ich weiss auch, dass ich im Nachhinein gewisse Dinge anders machen würde (im Nachhinein ist man immer schlauer). Vielleicht wärst du ja so nett und würdest mir einen konkreten Tipp geben, wass du bezüglich des Dao anders anpacken würdest.
 
Ok. Das mit der Exception hat sich erledigt.
Ich weiss auch nicht mehr wieso ich da die ProjectId übergebe und nicht das Object Project.
Code:
<a4j:mediaOutput element="img" cacheable="false" session="true"
								createContent="#{projectReportHandler.generateStatusChartForProject}"
								value="#{projectHandler.projectRecord}" mimeType="image/jpeg" />
Somit ist es unnötig das Projekt nochmals zu selektieren und der Fehler ist weg.
 
Hallo Oliver

Sorry, ich war erst einwenig betupft aber du hattest natürlich absolut recht. Ich hab nun alle Dao's komplett überarbeitet. Codezeilen optimiert und sämtliche beginTransaction() entfernt.

Es funktioniert nun perfekt.

Danke für den guten Hinweis.
Grüsse
Alan
 
Zurück