-->
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.  [ 4 posts ] 
Author Message
 Post subject: Schnelligkeit beim Löschen der Daten
PostPosted: Fri Mar 30, 2007 4:52 am 
Newbie

Joined: Wed Apr 19, 2006 3:18 am
Posts: 9
Hallo,

ich habe Problem das ich eine Menge der Daten zu löschen habe und das dieses sehr lange dauert.
Kann ich vielleicht Daten Löschen ohne das ich über Hibernate dieses tue?
Gibt es Möglichkeit die Geschwindigkeit zu verbessern, indem ich vielleciht meinen unten stehenden Code ändere?

Name and version of the database you are using:
MySQL

Source Code
public class DeleteBLSVersionen extends BaseLongRunningJob {

private static Logger logger = Logger.getLogger(DeleteBLSVersionen.class);

private int C_MAX= 100; // Dient um jedes Objekt mit diesen Wert zu multiplizieren um ungäfähre Anzahl der Daten die zu duplizieren zu eraten.

private int C_TRANSACTION= 500; // Dient um nach diesen Anzahl der Datensätze die transaktion durchzufphren.

private int blsversionid;

private Blsversion blsversion= null;

private BlsversionDAO blsversionDAO= new BlsversionDAO();

private Session ses= null;

protected BlsdatDAO blsdatDAO= new BlsdatDAO();

public DeleteBLSVersionen(int blsversionid, String threadtyp, int length) {
super("", threadtyp, length);
this.blsversionid= blsversionid;
}

public DeleteBLSVersionen(int blsversionid, String threadtyp) {
this(blsversionid, threadtyp, StringConstants.HALF_HOUR);
}

private void updateDescription() {
if (blsversion==null) {
return;
}
setBeschreibung(MessageFormat.format(StringConstants.DESCRIPTION_VERSION_DELETE, blsversion.getBezeichnung()));
updateStatus();
}

public Session getSession() {
AuditLogInterceptor interceptor= new AuditLogInterceptor();
Session ses= HibernateUtil.getSessionFactory().openSession(interceptor);
interceptor.setSession(ses);
return ses;
}

public static Field[] getAllFields(Class objectClass, Field[] fields) {

Field[] newFields = objectClass.getDeclaredFields();

int fieldsSize = 0;
int newFieldsSize = 0;

if(fields != null) {
fieldsSize = fields.length;
}

if(newFields != null) {
newFieldsSize = newFields.length;
}

Field[] totalFields = new Field[fieldsSize + newFieldsSize];

if(fieldsSize > 0) {
System.arraycopy(fields, 0, totalFields, 0, fieldsSize);
}

if(newFieldsSize > 0) {
System.arraycopy(newFields, 0, totalFields, fieldsSize, newFieldsSize);
}

Class superClass = objectClass.getSuperclass();

Field[] finalFieldsArray;

if (superClass != null && ! superClass.getName().equals("java.lang.Object")) {
finalFieldsArray = getAllFields(superClass, totalFields);
} else {
finalFieldsArray = totalFields;
}

return finalFieldsArray;
}

/**
* Die Methode delete sucht nach Referenzklassen und löscht diese zuerst.
* @param object Enthält die Daten der Referenzklassen.
*/
private void delete(Object object) {
if (object==null) {
return;
}
Class objectClass= object.getClass();
Field[] fields = Utilities.getAllFields(objectClass, null);
int nFLength= fields.length;

fieldIteration: for (int ii= nFLength-1; ii>=0; ii--) {
fields[ii].setAccessible(true);
if(Modifier.isTransient(fields[ii].getModifiers())
|| Modifier.isFinal(fields[ii].getModifiers())
|| Modifier.isStatic(fields[ii].getModifiers())) {
continue fieldIteration;
}
try {
Object objPropNewState = fields[ii].get(object);
if (objPropNewState instanceof java.util.Set) {
Iterator i= ((Set) objPropNewState).iterator();
while (i.hasNext()) {
Object newObject= (Object) i.next();
String clasz= Utilities.getClassName(newObject.getClass());
delete(newObject);
ses.delete(newObject);
logger.info(MessageFormat.format(StringConstants.LOGGER_DELETE_SUBDATA, (new Object[] {clasz})));
}
}
} catch (Exception e) {
setFehler(objectClass+": "+e.getMessage());
String msg = StringConstants.ERROR_MSG + e.getMessage();
logger.error(msg, e);
}
}
}

/**
* Die Methode findBLSVersionenAndDelete sucht nach Referenzklassen und löscht diese zuerst.
* @param object Enthält die Daten der Referenzklassen.
*/
private void findBLSVersionenAndDelete(Object object) {
if (object==null) {
return;
}
int count= 0;
String clasz= "";
String tmpClasz= "";
Transaction tx = null;
Class objectClass= object.getClass();
Field[] fields = Utilities.getAllFields(objectClass, null);
int nFLength= fields.length;

fieldIteration: for (int ii= nFLength-1; ii>=0; ii--) {
fields[ii].setAccessible(true);
if(Modifier.isTransient(fields[ii].getModifiers())
|| Modifier.isFinal(fields[ii].getModifiers())
|| Modifier.isStatic(fields[ii].getModifiers())) {
continue fieldIteration;
}
try {
Object objPropNewState = fields[ii].get(object);
if (objPropNewState instanceof java.util.Set) {
Iterator i= ((Set) objPropNewState).iterator();
setGesamtzeilen(getGesamtzeilen()+((Set)objPropNewState).size()-(C_MAX*10));
while (i.hasNext()) {
Object newObject= (Object) i.next();
if ((count % C_TRANSACTION)==0) {
tx =ses.beginTransaction();
}
try {
tmpClasz= Utilities.getClassName(newObject.getClass());
delete(newObject);
ses.delete(newObject);
count++;
if (((count % C_TRANSACTION)==0) || (!clasz.equalsIgnoreCase(tmpClasz))) {
clasz= tmpClasz;
count= 0;
tx.commit();
}
} catch (HibernateException e) {
setFehler(e.getMessage());
tx.rollback();
String msg = StringConstants.ERROR_MSG + e.getMessage();
logger.error(msg, e);
} catch (InfrastructureException e) {
setFehler(e.getMessage());
String msg = StringConstants.ERROR_MSG + e.getMessage();
logger.error(msg, e);
}
}
}
} catch (Exception e) {
setFehler(objectClass+": "+e.getMessage());
String msg = StringConstants.ERROR_MSG + e.getMessage();
logger.error(msg, e);
}
}
try {
if ((count % C_TRANSACTION)!=0) {
tx.commit();
}
} catch (HibernateException e) {
setFehler(e.getMessage());
tx.rollback();
String msg = StringConstants.ERROR_MSG + e.getMessage();
logger.error(msg, e);
} catch (InfrastructureException e) {
setFehler(e.getMessage());
String msg = StringConstants.ERROR_MSG + e.getMessage();
logger.error(msg, e);
}
}

@Override
protected boolean runLongJob() {
ses = getSession();
blsversion= blsversionDAO.get(blsversionid, ses);
if (blsversion==null) {
return false;
}
try {
findBLSVersionenAndDelete(blsversion);
Transaction tx =ses.beginTransaction();
try {
blsversionDAO.delete(blsversionid, ses);
tx.commit();
logger.info(MessageFormat.format(StringConstants.LOGGER_DELETE_HEAD_END, (new Object[] {Utilities.getClassName(Blsversion.class), blsversion.getUserVisibleId()})));
} catch (HibernateException e) {
setFehler(e.getMessage());
tx.rollback();
String msg = StringConstants.ERROR_MSG + e.getMessage();
logger.error(msg, e);
} catch (InfrastructureException e) {
setFehler(e.getMessage());
String msg = StringConstants.ERROR_MSG + e.getMessage();
logger.error(msg, e);
}
} finally {
ses.close();
}
return true;
}
}


mfg,
Stasa Jerinic


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 03, 2007 5:10 pm 
Expert
Expert

Joined: Tue Nov 23, 2004 7:00 pm
Posts: 570
Location: mostly Frankfurt Germany
Man kann quellkode auch in das code tag packen. Dann kann man ihn auch lesen. Ist es notwendig die Daten in einer Transaktion zu löschen? Das wäre mein erster Vorschlag.

Zweitens, vielleicht gibt es ja auch eine query ("delete from ... where ...", die Du innerhalb von Hibernate ausführen kannst.

_________________
Best Regards
Sebastian
---
Training for Hibernate and Java Persistence
Tutorials for Hibernate, Spring, EJB, JSF...
eBook: Hibernate 3 - DeveloperGuide
Paper book: Hibernate 3 - Das Praxisbuch
http://www.laliluna.de


Top
 Profile  
 
 Post subject: Löschen der Daten ohne Transaktion.
PostPosted: Tue Apr 10, 2007 12:49 am 
Newbie

Joined: Wed Apr 19, 2006 3:18 am
Posts: 9
Danke für den Tip.

Ich hätte eine weitere Frage bezüglich dem Löschen der Daten ohne die Transaktion zu benützen?
Wie mach ich das am besten, denn alle Möglichkeiten die ich über Session versucht habe, haben fehlgeschlagen. Es werden die Daten aus der Session gelöscht ohne das die Datenbank was davon mitbekommt. Falls es so funktioniert, das zuerst aus der Session die Daten gelöscht werden und erst zum Schluss der Datenbank mitgeteilt wird, dann kann ich es nicht auf dieser Weise realisieren, denn meine Webapplikation stürzt ab. Ich bekomme HeapMemory out of size, obwohl ich mit 750MB die Heapmemory initialisiere.

mfg,
Stasa Jerinic


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 10, 2007 2:05 am 
Expert
Expert

Joined: Tue Nov 23, 2004 7:00 pm
Posts: 570
Location: mostly Frankfurt Germany
Ohne Transaktion geht natürlich auch nicht.

Wenn man viele Daten löscht oder einfügt, gibt es zwei Möglichkeiten
Code:
Transaktion starten
for (...){
  Löschen/Einfügen

  alle x (z.B. 100)
  {
// SQL Befehle schreiben und Session leeren
    sesssion.flush();
    session.clear();
}
}
Transaktion beenden

oder

Code:
for (...){
  Löschen/Einfügen

  alle x (z.B. 100)
  {
    Transaktion beenden
    Transaktion starten
}
}
Transaktion beenden

_________________
Best Regards
Sebastian
---
Training for Hibernate and Java Persistence
Tutorials for Hibernate, Spring, EJB, JSF...
eBook: Hibernate 3 - DeveloperGuide
Paper book: Hibernate 3 - Das Praxisbuch
http://www.laliluna.de


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

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.