简体   繁体   English

android.database.sqlite.SQLiteConstraintException: UNIQUE 约束使用 greenDAO ORM 失败

[英]android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed using greenDAO ORM

I am using GreenDAO for a local Android project.我将GreenDAO用于本地 Android 项目。 I am creating the login and register of the users (they work fine) the problem happens after one user is created.我正在创建用户的登录名和注册(他们工作正常),问题发生在创建一个用户之后。 Registering more than one user throws this exception:注册多个用户会引发此异常:

    E/SQLiteLog: (1555) abort at 21 in [INSERT INTO "USER" ("_id","EMAIL","FIRST_NAME","LAST_NAME","LAND","PASSWORD","IMAGE_REFERENCE","ABOUT","ROLE_ID") VALUES (?,?,?,?,?,?,?,?,?)]: UNIQUE constraint failed: USER._id
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.databaseproject, PID: 7436
    android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: USER._id (code 1555)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:782)
        at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
        at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
        at org.greenrobot.greendao.AbstractDao.insertInsideTx(AbstractDao.java:368)
        at org.greenrobot.greendao.AbstractDao.executeInsert(AbstractDao.java:351)
        at org.greenrobot.greendao.AbstractDao.insert(AbstractDao.java:319)
        at com.example.databaseproject.activity.MainActivity.register(MainActivity.java:107)
        at com.example.databaseproject.activity.MainActivity.access$500(MainActivity.java:23)
        at com.example.databaseproject.activity.MainActivity$1.onClick(MainActivity.java:69)
        at android.view.View.performClick(View.java:4756)
        at android.view.View$PerformClick.run(View.java:19749)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

Although I have set the user id to @Id(autoIncrement = true) it seems as if the new Users are getting the same id.尽管我已将用户 ID 设置为@Id(autoIncrement = true) ,但新用户似乎获得了相同的 ID。 Also the INSERT INTO sql shows (?,?, ...) for all property values in the console.此外, INSERT INTO sql 在控制台中显示所有属性值的(?,?, ...) What am I doing wrong here?我在这里做错了什么? This is my User.java这是我的User.java

package com.example.databaseproject.entity;

import androidx.annotation.Nullable;

import org.greenrobot.greendao.DaoException;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.JoinEntity;
import org.greenrobot.greendao.annotation.NotNull;
import org.greenrobot.greendao.annotation.ToMany;
import org.greenrobot.greendao.annotation.Unique;

import java.util.List;

@Entity
public class User {

    @Id(autoincrement = true)
    private long id;

    @NotNull
    @Unique
    private String email;
    @Nullable
    private String first_name;
    @Nullable
    private String last_name;
    @Nullable
    private String land;
    @NotNull
    private String password;
    @Nullable
    private String image_reference;
    @Nullable
    private String about;
    @NotNull
    private long role_id;

    @ToMany
    @JoinEntity(
            entity = UserMusicLiked.class,
            sourceProperty = "user_id",
            targetProperty = "music_id"
    )
    private List<Music> musicsLikedByThisUser;

    @ToMany
    @JoinEntity(
            entity = UserPlaylistFollow.class,
            sourceProperty = "user_id",
            targetProperty = "playlist_id"
    )
    private List<Playlist> playlistsFollowedByThisUser;

    /**
     * Used to resolve relations
     */
    @Generated(hash = 2040040024)
    private transient DaoSession daoSession;

    /**
     * Used for active entity operations.
     */
    @Generated(hash = 1507654846)
    private transient UserDao myDao;

    @Generated(hash = 1603819663)
    public User(long id, @NotNull String email, String first_name, String last_name, String land,
                @NotNull String password, String image_reference, String about, long role_id) {
        this.id = id;
        this.email = email;
        this.first_name = first_name;
        this.last_name = last_name;
        this.land = land;
        this.password = password;
        this.image_reference = image_reference;
        this.about = about;
        this.role_id = role_id;
    }

    @Generated(hash = 586692638)
    public User() {
    }

    public long getId() {
        return this.id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getEmail() {
        return this.email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getFirst_name() {
        return this.first_name;
    }

    public void setFirst_name(String first_name) {
        this.first_name = first_name;
    }

    public String getLast_name() {
        return this.last_name;
    }

    public void setLast_name(String last_name) {
        this.last_name = last_name;
    }

    public String getLand() {
        return this.land;
    }

    public void setLand(String land) {
        this.land = land;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getImage_reference() {
        return this.image_reference;
    }

    public void setImage_reference(String image_reference) {
        this.image_reference = image_reference;
    }

    public String getAbout() {
        return this.about;
    }

    public void setAbout(String about) {
        this.about = about;
    }

    public long getRole_id() {
        return this.role_id;
    }

    public void setRole_id(long role_id) {
        this.role_id = role_id;
    }

    /**
     * To-many relationship, resolved on first access (and after reset).
     * Changes to to-many relations are not persisted, make changes to the target entity.
     */
    @Generated(hash = 1624161576)
    public List<Music> getMusicsLikedByThisUser() {
        if (musicsLikedByThisUser == null) {
            final DaoSession daoSession = this.daoSession;
            if (daoSession == null) {
                throw new DaoException("Entity is detached from DAO context");
            }
            MusicDao targetDao = daoSession.getMusicDao();
            List<Music> musicsLikedByThisUserNew = targetDao._queryUser_MusicsLikedByThisUser(id);
            synchronized (this) {
                if (musicsLikedByThisUser == null) {
                    musicsLikedByThisUser = musicsLikedByThisUserNew;
                }
            }
        }
        return musicsLikedByThisUser;
    }

    /**
     * Resets a to-many relationship, making the next get call to query for a fresh result.
     */
    @Generated(hash = 1901439151)
    public synchronized void resetMusicsLikedByThisUser() {
        musicsLikedByThisUser = null;
    }

    /**
     * To-many relationship, resolved on first access (and after reset).
     * Changes to to-many relations are not persisted, make changes to the target entity.
     */
    @Generated(hash = 952184019)
    public List<Playlist> getPlaylistsFollowedByThisUser() {
        if (playlistsFollowedByThisUser == null) {
            final DaoSession daoSession = this.daoSession;
            if (daoSession == null) {
                throw new DaoException("Entity is detached from DAO context");
            }
            PlaylistDao targetDao = daoSession.getPlaylistDao();
            List<Playlist> playlistsFollowedByThisUserNew = targetDao
                    ._queryUser_PlaylistsFollowedByThisUser(id);
            synchronized (this) {
                if (playlistsFollowedByThisUser == null) {
                    playlistsFollowedByThisUser = playlistsFollowedByThisUserNew;
                }
            }
        }
        return playlistsFollowedByThisUser;
    }

    /**
     * Resets a to-many relationship, making the next get call to query for a fresh result.
     */
    @Generated(hash = 1490831360)
    public synchronized void resetPlaylistsFollowedByThisUser() {
        playlistsFollowedByThisUser = null;
    }

    /**
     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
     * Entity must attached to an entity context.
     */
    @Generated(hash = 128553479)
    public void delete() {
        if (myDao == null) {
            throw new DaoException("Entity is detached from DAO context");
        }
        myDao.delete(this);
    }

    /**
     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.
     * Entity must attached to an entity context.
     */
    @Generated(hash = 1942392019)
    public void refresh() {
        if (myDao == null) {
            throw new DaoException("Entity is detached from DAO context");
        }
        myDao.refresh(this);
    }

    /**
     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.
     * Entity must attached to an entity context.
     */
    @Generated(hash = 713229351)
    public void update() {
        if (myDao == null) {
            throw new DaoException("Entity is detached from DAO context");
        }
        myDao.update(this);
    }

    /** called by internal mechanisms, do not call yourself. */
    @Generated(hash = 2059241980)
    public void __setDaoSession(DaoSession daoSession) {
        this.daoSession = daoSession;
        myDao = daoSession != null ? daoSession.getUserDao() : null;
    }
}

This is my MainActivity.java这是我的MainActivity.java

package com.example.databaseproject.activity;

import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.databaseproject.CurrentUser;
import com.example.databaseproject.R;
import com.example.databaseproject.entity.DaoMaster;
import com.example.databaseproject.entity.DaoSession;
import com.example.databaseproject.entity.User;
import com.example.databaseproject.entity.UserDao;

import java.util.List;

public class MainActivity extends AppCompatActivity {


    private boolean isLogin = true;

    private EditText emailEditText;
    private EditText passwordEditText;
    private EditText firstNameEditText;
    private EditText lastNameEditText;
    private EditText landNameEditText;
    private Spinner roleSpinner;

    private TextView changeLoginRegisterText;
    private Button submitButton;

    private DaoSession daoSession;
    private UserDao userDao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


// do this once, for example in your Application class
        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "myDatabase", null);
        SQLiteDatabase db = helper.getWritableDatabase();
        DaoMaster daoMaster = new DaoMaster(db);
        daoSession = daoMaster.newSession();
        userDao = daoSession.getUserDao();
// do this in your activities/fragments to get hold of a DAO
//        MusicDao musicEntity = daoSession.getMusicDao();

        emailEditText = findViewById(R.id.edit_text_username);
        passwordEditText = findViewById(R.id.edit_text_password);
        submitButton = findViewById(R.id.button_submit);
        changeLoginRegisterText = findViewById(R.id.text_view_register);

        submitButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (isLogin) {
                    if (isFieldsValid())
                        login(emailEditText.getText().toString(), passwordEditText.getText().toString());
                } else {
                    if (isFieldsValid())
                        register(emailEditText.getText().toString(), passwordEditText.getText().toString());
                }
            }
        });

        changeLoginRegisterText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                isLogin = !isLogin;
                updateUI();
            }
        });
    }

    private void updateUI() {
        if (isLogin) {
            changeLoginRegisterText.setText("Not a user? Create a new Account");
            submitButton.setText("Login");
        } else {
            changeLoginRegisterText.setText("Already a User? Login");
            submitButton.setText("Register");
        }
    }

    private void register(String email, String password) {

        //Check if user exists

        List<User> user = userDao.queryBuilder().where(UserDao.Properties.Email.eq(email))
                .limit(1)
                .list();
        if (user != null && user.size() > 0) {
            print(user.get(0).getEmail() + " Already Registered");
        } else {
            User newUser = new User();
            newUser.setEmail(email);
            newUser.setPassword(password);
            newUser.setRole_id(0);
            userDao.insert(newUser);
            print(newUser.getEmail() + " Registered successfully");

            setCurrentUser(newUser);
        }
    }

    private void login(String email, String password) {
//        UserDao userDao = daoSession.getUserDao();
        List<User> user = userDao.queryBuilder().where(UserDao.Properties.Email.eq(email))
                .where(UserDao.Properties.Password.eq(password))
                .limit(1)
                .list();
        if (user != null && user.size() > 0) {
            print(user.get(0).getEmail() + " Logged in");
            setCurrentUser(user.get(0));
        } else {
            print("Invalid Username or Password");
        }
    }

    private void setCurrentUser(User user) {
        CurrentUser.user = user;

    }

    private void print(String message) {
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }

    private boolean isFieldsValid() {
        return emailEditText != null && !emailEditText.getText().toString().equals("")
                && passwordEditText != null && !passwordEditText.getText().toString().equals("");
    }
}

There are other entities as well, but I don't think they are related to the error.还有其他实体,但我认为它们与错误无关。 Tell me if you need more info.如果您需要更多信息,请告诉我。

I changed the id type of long to Long and regenerated the greenDAO code and it works now.我将long的 id 类型更改为Long并重新生成了 greenDAO 代码,它现在可以工作了。 Looks like auto increment doesn't work well with the type long .看起来自动增量不适用于long类型。 (Although in the documents it says both types are supported) (虽然在文档中说这两种类型都支持)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 android.database.sqlite.SQLiteConstraintException:唯一约束失败 - android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed 通过房间向数据库插入数据时崩溃:引起:android.database.sqlite.SQLiteConstraintException:UNIQUE 约束失败 - crash when insert data to database via room:Caused by: android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed android.database.sqlite.SQLiteConstraintException: UNIQUE 约束失败无法弄清楚错误说的是什么 - android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed Couldnot figure out what the error says android.database.sqlite.SQLiteConstraintException:错误代码19:约束失败 - android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed Room DB迁移的致命异常:android.database.sqlite.SQLiteConstraintException:UNIQUE约束失败 - Fatal Exception on Room DB Migration: android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed 错误崩溃RoomRate原因:android.database.sqlite.SQLiteConstraintException:唯一约束失败:products.id(代码1555) - error crash RoomCaused by: android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: products.id (code 1555) android.database.sqlite.SQLiteConstraintException:FOREIGN KEY约束失败(Sqlite代码787 SQLITE_CONSTRAINT_FOREIGNKEY) - android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (Sqlite code 787 SQLITE_CONSTRAINT_FOREIGNKEY) android.database.sqlite.SQLiteConstraintException - android.database.sqlite.SQLiteConstraintException Android RoomDB 自定义更新查询给出 android.database.sqlite.SQLiteConstraintException: NOT NULL 约束失败: - Android RoomDB custom update query gives android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: 插入android.database.sqlite.sqliteconstraintexception错误代码19约束失败 - error inserting android.database.sqlite.sqliteconstraintexception error code 19 constraint failed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM