android Room 질문좀드리겠습니다(소스코드 새로올렸습니다 두번째!)

조회수 914회

현재 번역을 할수있는어플을 토이프로젝트로 구현중에있습니다

번역할 한국말을 입력하고 영어로 번역을하게되면

데이터베이스에 저장을하고

번역을 했었던 데이터들을 리사이클러뷰로 가지고오는 어플을 만들고있는데요

모든 작업은 Fragment 위에서 이루어지고있습니다

통신은 Retrofit2 라이브러리를 사용하고있습니다

데이터베이스는 Romm 라이브러리를 사용하고있습니다

문제는 Retrofit2 에서 응답받은 데이터가 Insert 가 안되고있습니다

오류는 현재 이런식으로 뜨고있습니다..

java.lang.RuntimeException: An error occurred while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:353) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383) at java.util.concurrent.FutureTask.setException(FutureTask.java:252) at java.util.concurrent.FutureTask.run(FutureTask.java:271) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) Caused by: android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: language_table.language (code 1299) at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method) at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:789) at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:926) at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86) at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:79) at android.arch.persistence.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.java:114) at com.example.toyproject.Model.LanguageDao_Impl.insert(LanguageDao_Impl.java:96) at com.example.toyproject.Model.LanguageRepository$1.doInBackground(LanguageRepository.java:35) at com.example.toyproject.Model.LanguageRepository$1.doInBackground(LanguageRepository.java:23) at android.os.AsyncTask$2.call(AsyncTask.java:333) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)  at java.lang.Thread.run(Thread.java:764)

Room에서 insert 할때 AsyncTask 쓰는데 이때 doInbackground 에서 무언가 잘못된거같은데 그 이유를 잘 모르겠습니다..

Retrofit2 부분입니다!

public Translate(TotalPresent.GetData present) {
    this.present = present;
    languageData = new LanguageData();
}

@Override
public void translatedata(String change, String text){
    retrofit = new Retrofit.Builder()
            .baseUrl(PapagoService.URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    PapagoService papagoService = retrofit.create(PapagoService.class);

    HashMap<String,Object> param = new HashMap<>();
    param.put("source","ko");
    param.put("target",change);
    param.put("text",text);

    papagoService.getResult(param).enqueue(new Callback<Result>() {
        @Override
        public void onResponse(Call<Result> call, Response<Result> response) {
            if(response.isSuccessful()){
                Result result = response.body();
                Message message = result.getMessage();
                DetailData detailData = message.getDetailData();
                present.getData(detailData.getTranslatedText()); //통신해서 UI에 응답결과를보여줍니다
                languageData.postData(text,detailData.getTranslatedText()); //통신해서 DB데이터로 저장하기위해서 데이터를 넘겨줍니다
            }
        }

        @Override
        public void onFailure(Call<Result> call, Throwable t) {

        }
    });
}

}

present.getData(detailData.getTranslatedText()); //통신해서 UI에 응답결과를보여줍니다 languageData.postData(text,detailData.getTranslatedText()); //통신해서 DB데이터로 저장하기위해서 데이터를 넘겨줍니다

public void setModel(RecyclerView recyclerView, RecyclerViewAdpater recyclerViewAdpater){
    model = ViewModelProviders.of(recyclerView).get(Model.class);
    model.getAllLanguage().observe(recyclerView, languages -> recyclerViewAdpater.setData(languages));
}

public void postData(String text,String text2){
    this.text = text; // 이부분
    this.text2 = text2; //이부분 
}


public void setLanguage() {
    try {
        Language language = new Language();
        language.setLanguage(text); //넘겨받은데이터를 가져옵니다
        language.setLanguage2(text2);//넘겨받은데이터를 가져옵니다
        model.insert(language);
    }catch (Exception e){
        e.printStackTrace();
    }
}

Retrofit2 에서 DB로 넘겨진 데이터는 바로 위 소스코드로 넘겨받게 작성했습니다

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    binding = DataBindingUtil.inflate(inflater,R.layout.recycler_view,container,false);
    languageData = new LanguageData();
    recyclerViewAdpater = new RecyclerViewAdpater(getContext());

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(),LinearLayoutManager.VERTICAL,false);
    binding.recyclerview.setLayoutManager(linearLayoutManager);
    binding.recyclerview.setAdapter(recyclerViewAdpater);

    languageData.setModel(this, recyclerViewAdpater);
    languageData.setLanguage(); // 아까 데이터받은 메소드를 여기서 호출합니다
    //이부분에서 오류가납니다..
    return binding.getRoot();
}

위 소스코드는 RecyclerView 를 구현하기위한 소스코드입니다

아래소스코드는 오류가나는 데이터베이스 insert 문 입니다

public void insert(Language language) {

    new AsyncTask<Language, Void, Long>(){
        @Override
        protected void onPostExecute(Long aLong) {
            super.onPostExecute(aLong);
            Log.d(TAG, "insert : " + aLong);

        }

        @Override
        protected Long doInBackground(Language... languages) {
            if(languageDao == null)
                return -1L;
            return languageDao.insert(languages[0]);
        }
    }.execute(language);
}

아래 코드는 Dao 소스코드 부분입니다

@Dao
public interface LanguageDao {
    @Insert
    long insert(Language language);

    @Update
    int update(Language language);

    @Query("DELETE FROM language_table")
    int deleteAll();

    @Query("DELETE FROM language_table WHERE id = :id")
    int deleteLanguage(int id);

    @Query("SELECT * from language_table ORDER BY language ASC")
    LiveData<List<Language>> getAllLanguage();
}

아래코드는 Language 소스코드입니다

@Entity(tableName = "language_table")
public class Language {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    private int id;

    @NonNull
    @ColumnInfo(name = "language")
    private String language;

    @NonNull
    @ColumnInfo(name = "language2")
    private String language2;

    public int getId() {
        return id;
    }

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

    public void setLanguage(@NonNull String language) {
        this.language = language;
    }

    public String getLanguage() {
        return language;
    }

    @NonNull
    public String getLanguage2() {
        return language2;
    }

    public void setLanguage2(@NonNull String language2) {
        this.language2 = language2;
    }
}

지금 이시간에도 이것저것만져보고있는데 잘안풀리네요

  • 중요한 부분은 쏙 빼시고 질문하신것같습니다 ㅜㅜㅜㅜ 김은기 2019.11.5 22:07
  • 마지막에 languages[0] 이 부분이 null 인가요? Dao 의 insert 함수와 Language 클래스를 올려주세요. 김은기 2019.11.5 22:07
  • 은기님 말씀하신 부분의 소스코드 올려놨습니다! sdf7895 2019.11.6 01:27
  • 다시 확인해보니까 setLanguages 메소드부분에 데이터가 아예 넘어가지를 않습니다..ㅠㅠ sdf7895 2019.11.6 01:33
  • setLanguages.. 뒤에 s가 붙은 함수를 찾을수가 없어 어딘지 모르겠습니다... 아무튼 language_table 에서 논널 제약조건을 전부 해제하시고 구현해보신다음에 데이터가 어떻게 들어가나 확인해보세요 김은기 2019.11.6 01:51
  • 아 죄송합니다.. setLanguage 이 함수였습니다.. 네알겠습니다 시도해볼게요! sdf7895 2019.11.6 02:05
  • 은기님..Room라이브러리는 LiveData 와 비동기에대한 이해가 좀 부족해서 더 공부한뒤에 쓰려고합니다..그냥 SQlite 구현해서쓰려구여..댓글과 답변 감사했습니다 sdf7895 2019.11.6 11:33
  • 네 화이팅 김은기 2019.11.6 12:38

1 답변

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)