java - 当有事务正在进行时,无法启用或禁用 SQLite 外键约束

标签 java android database sqlite

我想要一个有点类似于我用来存储信息的 MySql 数据库的 Sqlite 数据库。在 Sqlite 中,外键默认是禁用的。

当我尝试使用“setForeignKeyConstraintsEnabled()”命令时,出现以下错误。

java.lang.IllegalStateException: Foreign Key Constraints cannot be enabled or disabled while there are transactions in progress. Finish all transactions and release all active database connections first.

如何解决这个问题?

注册 Activity

    package e.adin_pc.spark;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import java.util.HashMap;
import java.util.Map;





public class Register extends AppCompatActivity {

    EditText Username,Password,Email,Birthday;
    Button Register;
    String insertURL = "http://10.0.2.2/skripte/insert_user.php";
    RequestQueue requestQueue;
    private DatabaseHandler db;
    private static final String TAG = "RegisterActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);

        Username=findViewById(R.id.UserNameReg_EditText);
        Password=findViewById(R.id.PasswordReg_EditText);
        Email=findViewById(R.id.EmailReg_EditText);
        Birthday=findViewById(R.id.BirthdayReg_EditText);
        Register=findViewById(R.id.register_Button);

        db=new DatabaseHandler(this);

         requestQueue = Volley.newRequestQueue(getApplicationContext());


        Register.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                StringRequest stringRequest = new StringRequest(Request.Method.POST,

                        insertURL, new Response.Listener<String>() {

                    @Override

                    public void onResponse(String response) {
                        Toast.makeText(Register.this,response,Toast.LENGTH_LONG).show();

                        //Make object
                        Users user=new Users();
                        user.setId(Integer.parseInt(
                        user.setUserName(Username.toString());
                        user.setPassword(Password.toString());
                        user.setEmail(Email.toString());
                        user.setBirthday(Birthday.toString());
                        user.setIs_Admin(false);


                        //INSERT IS CALLED HERE 
                        boolean insert = db.InsertUser(user);

                        Log.i(TAG,"Uspjelo je valjda ",null);

                    }

                }, new Response.ErrorListener() {

                    @Override

                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(Register.this,error.toString(),Toast.LENGTH_LONG).show();




                    }

                }) {

                    @Override

                    protected Map<String, String> getParams() throws AuthFailureError {

                        Map<String, String> parameters = new HashMap<String, String>();

                        parameters.put("USERNAME", Username.getText().toString());

                        parameters.put("PASSWORD", Password.getText().toString());

                        parameters.put("EMAIL", Email.getText().toString());

                        parameters.put("BIRTHDAY", Birthday.getText().toString());



                        return parameters;

                    }

                };



                requestQueue.add(stringRequest);

            }

        });
    }
}

数据库处理程序代码

package e.adin_pc.spark;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Adin-PC on 3/30/2018.
 */

public class DatabaseHandler extends SQLiteOpenHelper {



    private static final String DATABASE_NAME = "Spark.db";
    private static final int VERSION = 1;

    //Tabela1
    private static final String table1_name="Users";
    private static final String Users_id = "Users_id";
    private static final String user_name = "user_name";
    private static final String password = "password";
    private static final String email = "email";
    private static final String birthday = "birthday";
    private static final String is_admin = "is_admin";
    //Table 2
    private static final String table2_name="Flights";
    private static final String Flights_id = "Flights_id";
    private static final String start_destination = "start_destination";
    private static final String end_destination = "end_destination";
    private static final String flight_start_time = "flight_start_time";
    private static final String Flight_end_time = "Flight_end_time";
    private static final String Price = "Price";
    //Table 3
    private static final String table3_name="User_flights";
    private static final String User_flights_id = "User_flights_id";
    private static final String User_fk = "User_fk";
    private static final String Flight_fk = "Flight_fk";


    public DatabaseHandler(Context context) {
        super(context, DATABASE_NAME, null, VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
         String Tb1Sql="CREATE TABLE "+table1_name+" ("+
                Users_id+" integer primary key , "+
                user_name+" text not null,"+
                password+" text not null,"+
                email+" text not null,"+
                birthday+" text not null,"+
                is_admin+" text not null"+" )";

        String Tb2Sql="CREATE TABLE "+table2_name+" ("+
                Flights_id+" integer primary key , "+
                start_destination+" text not null,"+
                end_destination+" text not null,"+
                flight_start_time+" text not null,"+
                Flight_end_time+" text not null,"+
                Price+" text not null"+" )";

        String Tb3Sql="CREATE TABLE "+table3_name+" ("+
                User_flights_id+" integer primary key , "+
                User_fk+" integer not null, "+
                "FOREIGN KEY ("+User_fk+") REFERENCES "+table1_name+"("+Users_id+"), "+
                Flight_fk+" integer not null, "+
                "FOREIGN KEY ("+Flight_fk+") REFERENCES "+table2_name+"("+Flights_id+")"+
                " )";

        db.setForeignKeyConstraintsEnabled(true); //ERROR IS HERE 
        //db.execSQL("PRAGMA foreign_keys=ON");  //THIS ALSO DOESNT WORK
        db.execSQL(Tb1Sql);
        db.execSQL(Tb2Sql);
        db.execSQL(Tb3Sql);



    }

    @Override
    public void onOpen(SQLiteDatabase db) {
        super.onOpen(db);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + table3_name);
        db.execSQL("DROP TABLE IF EXISTS " + table1_name);
        db.execSQL("DROP TABLE IF EXISTS " + table2_name);
        onCreate(db);
    }

//*---------------------------USER COMMANDS-------------------------------------------------------
 public boolean InsertUser(Users New_User){
        SQLiteDatabase db=this.getWritableDatabase();
        ContentValues values=new ContentValues();
        values.put(Users_id,New_User.getId());
        values.put(user_name,New_User.getUserName());
        values.put(password,New_User.getPassword());
        values.put(email,New_User.getEmail());
        values.put(birthday,New_User.getBirthday());
        values.put(is_admin,New_User.getIs_Admin());

        long result=db.insert(table1_name,null,values);
        db.close();

        if (result == -1) {
            return false;
        } else {
            return true;
        }
    }

public Users GetUser(String UserName, String Password){

     SQLiteDatabase db=this.getReadableDatabase();

     String Query="SELECT * FROM "+ table1_name+" WHERE "+user_name+" = "+UserName+" AND "+
             password+" = "+Password;



    Cursor c = db.rawQuery(Query, null);

    if (c != null)
        c.moveToFirst();

    Users user= new Users();
    user.setId(c.getInt(c.getColumnIndex(Users_id)));
    user.setUserName(c.getString(c.getColumnIndex(user_name)));
    user.setPassword(c.getString(c.getColumnIndex(password)));
    user.setEmail(c.getString(c.getColumnIndex(email)));
    user.setBirthday(c.getString(c.getColumnIndex(birthday)));

   String IsAdmin=c.getString(c.getColumnIndex(is_admin));
   String validation;
   if (IsAdmin=="true")
       user.setIs_Admin(true);
   else
       user.setIs_Admin(false);
    db.close();

   return user;




}










//*---------------------------FLIGTS COMMANDS-------------------------------------------------------

    public boolean InsertFlights(Flights New_flight){
        SQLiteDatabase db=this.getWritableDatabase();
        ContentValues values=new ContentValues();
        values.put(start_destination,New_flight.getStart_destination());
        values.put(end_destination,New_flight.getEnd_destination());
        values.put(flight_start_time,New_flight.getFlight_start_time());
        values.put(Flight_end_time,New_flight.getFlight_end_time());
        values.put(Price,New_flight.getPrice());

        long result=db.insert(table2_name,null,values);
        db.close();

        if (result == -1) {
            return false;
        } else {
            return true;
        }
    }

    /*
 * getting all flights under single user
 * */
    public List<Flights> getAllUSersFlights(long user_id) {
        List<Flights> flights = new ArrayList<Flights>();

        String selectQuery = "SELECT  * FROM " + table2_name +" INNER JOIN "+ table3_name+" ON "
                + table2_name+"."+Flights_id+" = "+table3_name+"."+Flight_fk+" WHERE "+table3_name+"."+User_fk+"="+user_id;



        SQLiteDatabase db = this.getReadableDatabase();
        Cursor c = db.rawQuery(selectQuery, null);

        // looping through all rows and adding to list
        if (c.moveToFirst()) {
            do {
                Flights td = new Flights();
                td.setId(c.getInt((c.getColumnIndex(Flights_id))));
                td.setStart_destination(c.getString(c.getColumnIndex(start_destination)));
                td.setEnd_destination(c.getString(c.getColumnIndex(end_destination)));
                td.setFlight_start_time(c.getString(c.getColumnIndex(flight_start_time)));
                td.setFlight_end_time(c.getString(c.getColumnIndex(Flight_end_time)));
                td.setPrice(c.getFloat(c.getColumnIndex(Price)));



                flights.add(td);
            } while (c.moveToNext());
        }
        db.close();

        return flights;
    }



    //*---------------------------USerFlights COMMANDS-------------------------------------------------------


    public boolean InsertUSerFlights(long user_id,long flight_id ){
        SQLiteDatabase db=this.getWritableDatabase();
        ContentValues values=new ContentValues();
        values.put(User_fk, user_id);
        values.put(Flight_fk, flight_id);


        long result=db.insert(table3_name,null,values);

        if (result == -1) {
            return false;
        } else {
            return true;
        }
    }





}

最佳答案

使用onConfigure()用于调用 setForeignKeyConstraintsEnabled() 的回调。

onCreate()运行在事务中执行。它也只运行一次,并且不会用于以后调用您的应用程序,因此它不适合设置外键杂注。

关于java - 当有事务正在进行时,无法启用或禁用 SQLite 外键约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49625588/

相关文章:

java - 通过 JDBC 的 Postgres 连接 : org. postgresql.util.PSQLException: ERROR: relation "prescriptions"does not exist

mysql - 对于公交车时刻表,我应该为所有公交车准备一个数据表并将时间表存储在一列中,还是为每辆公交车创建单独的表?

MySQL 分组图像解决方案?

java - mule/java - 从 java 类读取 jar 依赖项内部的属性文件

java - 应用程序崩溃 java.lang.NumberFormatException : Invalid int:

java - 什么是 PECS(生产者扩展消费者 super )?

java - 最小平均两片可塑性

android - 安全和不安全 cookie 之间的区别

android - MAT (Eclipse Memory Analyzer) - 如何从内存转储中查看位图

android - "Remotable"是什么意思?