j256 / ormlite-android

ORMLite Android functionality used in conjunction with ormlite-core
http://ormlite.com/
ISC License
1.59k stars 367 forks source link

Record deletion issue #97

Open Shahjahan786 opened 6 years ago

Shahjahan786 commented 6 years ago

I have a problem when deleting a record from table it returns 1 and also I try to read that record it returns null, but after some time when I read that record again it is present in table. find below is the log and code snippets

Version 5.0

06-07 09:58:04.989 20279-20279/com.my.app D/DialogDBOperation[read]: Dialog{dialogId='5b17bb462e23034b172cdf2f', lastMessage='created group', lastMessageDateSent=1528281933, lastMessageUserId=51826, photo='null', userId=51826, ownerId=51826, opponentId=-1, roomJid='16_5b17bb462e23034b172cdf2f@muc.chatmy.quickblox.com', unreadMessageCount=0, name='hellohi', occupantsIds=[51979], type=2, customData=QBBaseCustomObject{className='DialogMetaData', fields={admins=[51826,51979], isChatBlocked=false}}}
06-07 09:58:14.463 20279-20279/com.my.app D/DialogDBOperation[delete]: hellohidialog  deleted
06-07 09:58:14.542 20279-20279/com.my.app D/DialogDBOperation[read]: null > 5b17bb462e23034b172cdf2f
06-07 09:58:24.791 20279-20279/com.my.app D/DialogDBOperation[read]: Dialog{dialogId='5b17bb462e23034b172cdf2f', lastMessage='created group', lastMessageDateSent=1528281933, lastMessageUserId=51826, photo='null', userId=51826, ownerId=51826, opponentId=-1, roomJid='16_5b17bb462e23034b172cdf2f@muc.chatmy.quickblox.com', unreadMessageCount=0, name='hellohi', occupantsIds=[51979], type=2, customData=QBBaseCustomObject{className='DialogMetaData', fields={admins=[51826,51979], isChatBlocked=false}}}

Code snippets:

public int deleteById(String dialogId) throws SQLException {
        DatabaseConnection conn = dao.startThreadConnection();
        Savepoint savepoint = null;
        int deleted = 0;
        try {
            savepoint = conn.setSavePoint(null);
            DeleteBuilder<Dialog, String> deleteBuilder = dao.deleteBuilder();
            deleteBuilder.where().eq(Dialog.Column.ID, dialogId);
            deleted = deleteBuilder.delete();
            AppUtils.logDebug("QUERY", deleteBuilder.prepare().getStatement() + "  > DELETED? " + deleted);
        } finally {
            conn.commit(savepoint);
            dao.endThreadConnection(conn);
        }
        return deleted;
    }
public Dialog getByDialogId(String dialogId) {
        Dialog dialog = null;

        try {
            QueryBuilder<Dialog, String> queryBuilder = dao.queryBuilder();
            queryBuilder.where().eq(Dialog.Column.ID, dialogId);
            PreparedQuery<Dialog> preparedQuery = queryBuilder.prepare();
            dialog = dao.queryForFirst(preparedQuery);
            AppUtils.logDebug("QUERY[getByDialogId]", preparedQuery.getStatement());
        } catch (SQLException e) {
            ErrorUtils.logError(e);
        }

        return dialog;
    }

Object Class

@DatabaseTable
public class Dialog implements Serializable {

    @DatabaseField(id = true)
    @SerializedName("_id")
    private String dialogId;

    @DatabaseField
    @SerializedName("last_message")
    private String lastMessage;

    @DatabaseField
    @SerializedName("last_message_date_sent")
    private long lastMessageDateSent;

    @DatabaseField
    @SerializedName("last_message_user_id")
    private Integer lastMessageUserId;

    @DatabaseField
    @SerializedName("photo")
    private String photo;

    @DatabaseField
    @SerializedName("user_id")
    private Integer userId;

    @DatabaseField
    private Integer ownerId;

    @DatabaseField
    private Integer opponentId;

    @DatabaseField
    @SerializedName("xmpp_room_jid")
    private String roomJid;

    @DatabaseField
    @SerializedName("unread_messages_count")
    private Integer unreadMessageCount;

    @DatabaseField
    private String name;

    @DatabaseField(dataType = DataType.SERIALIZABLE)
    @SerializedName("occupants_ids")
    private ArrayList<Integer> occupantsIds;

    @DatabaseField
    private Integer type;

    @DatabaseField(dataType = DataType.SERIALIZABLE)
    @SerializedName("customData")
    private QBDialogCustomData customData;

    public String getDialogId() {
        return dialogId;
    }

    public void setDialogId(String dialogId) {
        this.dialogId = dialogId;
    }

    public String getLastMessage() {
        return lastMessage;
    }

    public void setLastMessage(String lastMessage) {
        this.lastMessage = lastMessage;
    }

    public long getLastMessageDateSent() {
        return lastMessageDateSent;
    }

    public void setLastMessageDateSent(long lastMessageDateSent) {
        this.lastMessageDateSent = lastMessageDateSent;
    }

    public Integer getLastMessageUserId() {
        return lastMessageUserId;
    }

    public void setLastMessageUserId(Integer lastMessageUserId) {
        this.lastMessageUserId = lastMessageUserId;
    }

    public String getPhoto() {
        return photo;
    }

    public void setPhoto(String photo) {
        this.photo = photo;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getRoomJid() {
        return roomJid;
    }

    public void setRoomJid(String roomJid) {
        this.roomJid = roomJid;
    }

    public Integer getUnreadMessageCount() {
        return unreadMessageCount;
    }

    public void setUnreadMessageCount(Integer unreadMessageCount) {
        this.unreadMessageCount = unreadMessageCount;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public ArrayList<Integer> getOccupantsIds() {
        return occupantsIds;
    }

    public void setOccupantsIds(ArrayList<Integer> occupantsIds) {
        this.occupantsIds = occupantsIds;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public Integer getOpponentId() {
        return opponentId;
    }

    public void setOpponentId(Integer opponentId) {
        this.opponentId = opponentId;
    }

    public QBDialogCustomData getCustomData() {
        return customData;
    }

    public void setCustomData(QBDialogCustomData customData) {
        this.customData = customData;
    }

    public Integer getOwnerId() {
        return ownerId;
    }

    public void setOwnerId(Integer ownerId) {
        this.ownerId = ownerId;
    }

    public static Dialog convert(QBChatDialog qbChatDialog){

        QBUser currentUser = ChatSharedPrefsHelper.getInstance().getQbUser();

        Dialog dialog = new Dialog();
        dialog.dialogId = qbChatDialog.getDialogId();
        dialog.lastMessage = qbChatDialog.getLastMessage();
        dialog.lastMessageDateSent = qbChatDialog.getLastMessageDateSent();
        dialog.lastMessageUserId = qbChatDialog.getLastMessageUserId();
        dialog.photo = qbChatDialog.getPhoto();
        dialog.userId = qbChatDialog.getUserId();
        dialog.roomJid = qbChatDialog.getRoomJid();
        dialog.unreadMessageCount = qbChatDialog.getUnreadMessageCount();
        dialog.name = qbChatDialog.getName();
        dialog.occupantsIds = new ArrayList<>(qbChatDialog.getOccupants());
        dialog.type = qbChatDialog.getType().getCode();
        dialog.customData = qbChatDialog.getCustomData();
        dialog.ownerId = currentUser != null ? currentUser.getId() : null;

        try{
            qbChatDialog.initForChat(QBChatService.getInstance());
            dialog.opponentId = qbChatDialog.getRecipientId();
        }catch (Exception e){
            if(currentUser != null){
                for (Integer occupantId : dialog.occupantsIds) {

                    if(!occupantId.equals(currentUser)){
                        dialog.opponentId = qbChatDialog.getRecipientId();
                        break;
                    }
                }
            }
        }

        return dialog;
    }

    public static QBChatDialog convert(Dialog dialog){
        QBChatDialog qbChatDialog = new QBChatDialog();
        qbChatDialog.setDialogId(dialog.dialogId);
        qbChatDialog.setLastMessage(dialog.lastMessage);
        qbChatDialog.setLastMessageDateSent(dialog.lastMessageDateSent);
        qbChatDialog.setLastMessageUserId(dialog.lastMessageUserId);
        qbChatDialog.setPhoto(dialog.photo);
        qbChatDialog.setUserId(dialog.userId);
        qbChatDialog.setRoomJid(dialog.roomJid);
        qbChatDialog.setUnreadMessageCount(dialog.unreadMessageCount);
        qbChatDialog.setName(dialog.name);
        qbChatDialog.setOccupantsIds(dialog.occupantsIds);
        qbChatDialog.setType(QBDialogType.parseByCode(dialog.type));
        qbChatDialog.setCustomData(dialog.customData);
        return qbChatDialog;
    }

    public static List<Dialog> convertList(List<QBChatDialog> qbChatDialogList){
        List<Dialog> dialogs = new ArrayList<>(qbChatDialogList.size());
        for (QBChatDialog qbChatDialog : qbChatDialogList){
            dialogs.add(Dialog.convert(qbChatDialog));
        }

        return dialogs;

    }

    public static List<QBChatDialog> convertToQBChatDialogList(List<Dialog> dialogs){
        List<QBChatDialog> qbChatDialogList = new ArrayList<>(dialogs.size());
        for (Dialog dialog : dialogs){
            qbChatDialogList.add(Dialog.convert(dialog));
        }

        return qbChatDialogList;

    }

    public int hashCode() {
        return this.getDialogId().hashCode();
    }

    public boolean equals(Object o) {
        if(this == o) {
            return true;
        } else if(o != null && this.getClass() == o.getClass()) {
            Dialog dialog = (Dialog) o;
            return this.getDialogId().equals(dialog.getDialogId());
        } else {
            return false;
        }
    }

    @Override
    public String toString() {
        return "Dialog{" +
                "dialogId='" + dialogId + '\'' +
                ", lastMessage='" + lastMessage + '\'' +
                ", lastMessageDateSent=" + lastMessageDateSent +
                ", lastMessageUserId=" + lastMessageUserId +
                ", photo='" + photo + '\'' +
                ", userId=" + userId +
                ", ownerId=" + ownerId +
                ", opponentId=" + opponentId +
                ", roomJid='" + roomJid + '\'' +
                ", unreadMessageCount=" + unreadMessageCount +
                ", name='" + name + '\'' +
                ", occupantsIds=" + occupantsIds +
                ", type=" + type +
                ", customData=" + customData +
                '}';
    }

    public interface Column{
        String ID = "dialogId";
        String NAME = "name";
        String USER_ID = "userId";
        String OWNER_ID = "ownerId";
        String LAST_MESSAGE_DATE_SENT = "lastMessageDateSent";
        String OPPONENT_ID = "opponentId";
        String TYPE = "type";
        String ROOM_ID = "roomJid";

    }

    public static Set<String> getIds(Collection<Dialog> dialogs) {
        Set<String> dialogIds = new HashSet<>();
        for (Dialog dialog : dialogs) {
            dialogIds.add(dialog.getDialogId());
        }
        return dialogIds;
    }
}
j256 commented 6 years ago

Any chance the 2nd lookup is in another savePoint started before the delete was called? I assume no one else is creating one of these? Once the delete is called, is the lookup that initially shows no results being called inside of the same savePoint or outside of it?

pedrodimoura commented 6 years ago

I got the same problem in my project.

Version: com.j256.ormlite:ormlite-android:5.1

I am just calling this method:

mSomeDao.getDao(aContext).delete(t);

't' is a Collection

And just happens with this object that is annotated with

@ForeignCollectionField(eager = true)

public abstract class MyAbstractClass {

@ForeignCollectionField(eager = true)
private Collection<MyChildClass> myChildClassCollection;

}
public class MyChildClass {
@DatabaseField(
            foreign = true,
            foreignAutoRefresh = true,
            columnName = MY_ABSTRACT_CLASS_ID,
            maxForeignAutoRefreshLevel = 0
    )
    private transient MyAbstractClass myAbstractClass;
}

Everything is going right when I use create method, but, when I try to use delete methods (delete(Collection), DeleteBuilder.delete()), doesn't work.

pedrodimoura commented 6 years ago

Hey, my algorithm on Job that deletes from database was wrong. I fixed. I was ignoring some rows because of my DeleteBuilder. My mistake. Everthing is ok!