Skip to content

Commit

Permalink
Fix the bug of saving a deleted model won't be succeeded.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tony Green committed Jan 22, 2015
1 parent adf191b commit 3397d3f
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 49 deletions.
46 changes: 0 additions & 46 deletions library/src/org/litepal/crud/AssociationsAnalyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,52 +35,6 @@
*/
abstract class AssociationsAnalyzer extends DataHandler {

/**
* Get the associated model.
*
* @param baseObj
* The instance of self model.
* @param associationInfo
* To get the associated model.
* @return The associated model of self model by analyzing associationInfo.
*
* @throws SecurityException
* @throws IllegalArgumentException
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
protected DataSupport getAssociatedModel(DataSupport baseObj, AssociationsInfo associationInfo)
throws SecurityException, IllegalArgumentException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException {
return (DataSupport) takeGetMethodValueByField(baseObj,
associationInfo.getAssociateOtherModelFromSelf());
}

/**
* Get the associated models collection. When it comes to many2one or
* many2many association. A model may have lots of associated models.
*
* @param baseObj
* The instance of self model.
* @param associationInfo
* To get the associated models collection.
* @return The associated models collection of self model by analyzing
* associationInfo.
* @throws SecurityException
* @throws IllegalArgumentException
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
@SuppressWarnings("unchecked")
protected Collection<DataSupport> getAssociatedModels(DataSupport baseObj,
AssociationsInfo associationInfo) throws SecurityException, IllegalArgumentException,
NoSuchMethodException, IllegalAccessException, InvocationTargetException {
return (Collection<DataSupport>) takeGetMethodValueByField(baseObj,
associationInfo.getAssociateOtherModelFromSelf());
}

/**
* Get the associated models collection of associated model. Used for
* reverse searching associations.
Expand Down
46 changes: 46 additions & 0 deletions library/src/org/litepal/crud/DataHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,52 @@ protected void analyzeAssociatedModels(DataSupport baseObj,
throw new DataSupportException(e.getMessage());
}
}

/**
* Get the associated model.
*
* @param baseObj
* The instance of self model.
* @param associationInfo
* To get the associated model.
* @return The associated model of self model by analyzing associationInfo.
*
* @throws SecurityException
* @throws IllegalArgumentException
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
protected DataSupport getAssociatedModel(DataSupport baseObj, AssociationsInfo associationInfo)
throws SecurityException, IllegalArgumentException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException {
return (DataSupport) takeGetMethodValueByField(baseObj,
associationInfo.getAssociateOtherModelFromSelf());
}

/**
* Get the associated models collection. When it comes to many2one or
* many2many association. A model may have lots of associated models.
*
* @param baseObj
* The instance of self model.
* @param associationInfo
* To get the associated models collection.
* @return The associated models collection of self model by analyzing
* associationInfo.
* @throws SecurityException
* @throws IllegalArgumentException
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
@SuppressWarnings("unchecked")
protected Collection<DataSupport> getAssociatedModels(DataSupport baseObj,
AssociationsInfo associationInfo) throws SecurityException, IllegalArgumentException,
NoSuchMethodException, IllegalAccessException, InvocationTargetException {
return (Collection<DataSupport>) takeGetMethodValueByField(baseObj,
associationInfo.getAssociateOtherModelFromSelf());
}

/**
* Create an empty instance of baseObj if it hasn't created one yet. If
Expand Down
10 changes: 9 additions & 1 deletion library/src/org/litepal/crud/DataSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,7 @@ public synchronized int delete() {
try {
DeleteHandler deleteHandler = new DeleteHandler(db);
int rowsAffected = deleteHandler.onDelete(this);
baseObjId = 0;
db.setTransactionSuccessful();
return rowsAffected;
} finally {
Expand Down Expand Up @@ -1101,7 +1102,7 @@ protected DataSupport() {
protected long getBaseObjId() {
return baseObjId;
}

/**
* Get the full class name of self.
*
Expand All @@ -1119,6 +1120,13 @@ protected String getClassName() {
protected String getTableName() {
return BaseUtility.changeCase(getClass().getSimpleName());
}

/**
* Reset the value of baseObjId. This means the model will become unsaved state.
*/
void resetBaseObjId() {
baseObjId = 0;
}

/**
* Get the list which holds all field names to update them into default
Expand Down
43 changes: 41 additions & 2 deletions library/src/org/litepal/crud/DeleteHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,11 @@ public class DeleteHandler extends DataHandler {
*/
int onDelete(DataSupport baseObj) {
if (baseObj.isSaved()) {
analyzeAssociations(baseObj);
Collection<AssociationsInfo> associationInfos = analyzeAssociations(baseObj);
int rowsAffected = deleteCascade(baseObj);
rowsAffected += mDatabase.delete(baseObj.getTableName(),
"id = " + baseObj.getBaseObjId(), null);
clearAssociatedModelSaveState(baseObj, associationInfos);;
return rowsAffected;
}
return 0;
Expand Down Expand Up @@ -194,11 +195,49 @@ private int deleteCascade(Class<?> modelClass, long id) {
* @param baseObj
* The record to delete.
*/
private void analyzeAssociations(DataSupport baseObj) {
private Collection<AssociationsInfo> analyzeAssociations(DataSupport baseObj) {
try {
Collection<AssociationsInfo> associationInfos = getAssociationInfo(baseObj
.getClassName());
analyzeAssociatedModels(baseObj, associationInfos);
return associationInfos;
} catch (Exception e) {
throw new DataSupportException(e.getMessage());
}
}

/**
* Clear associated models' save state. After this method, the associated
* models of baseObj which data is removed from database will become
* unsaved.
*
* @param baseObj
* The record to delete.
* @param associationInfos
* The associated info.
*/
private void clearAssociatedModelSaveState(DataSupport baseObj, Collection<AssociationsInfo> associationInfos) {
try {
for (AssociationsInfo associationInfo : associationInfos) {
if (associationInfo.getAssociationType() == Const.Model.MANY_TO_ONE
&& !baseObj.getClassName().equals(
associationInfo.getClassHoldsForeignKey())) {
Collection<DataSupport> associatedModels = getAssociatedModels(
baseObj, associationInfo);
if (associatedModels != null && !associatedModels.isEmpty()) {
for (DataSupport model : associatedModels) {
if (model != null) {
model.resetBaseObjId();
}
}
}
} else if (associationInfo.getAssociationType() == Const.Model.ONE_TO_ONE) {
DataSupport model = getAssociatedModel(baseObj, associationInfo);
if (model != null) {
model.resetBaseObjId();
}
}
}
} catch (Exception e) {
throw new DataSupportException(e.getMessage());
}
Expand Down

0 comments on commit 3397d3f

Please sign in to comment.