Как определить несколько объектов? - PullRequest
0 голосов
/ 07 июля 2019

В настоящее время я создаю приложение управления запасами для деятельности в точках продаж. Здесь я должен включить функцию базы данных с 3 таблицами: пункт , счет и корзина . В соответствии с официальной документацией Android (https://developer.android.com/training/data-storage/sqlite), настоятельно рекомендуется использовать библиотеку Room из-за недостатка без него: без проверки во время компиляции, большого количества стандартного кода. После этого я решил попробовать .

Во-первых, я начал тестировать реализацию Room, используя одну таблицу. Чтобы определить item , я создал 3 объекта: Item class, ItemDao interface и POSDatabase class. В результате все запросы выполняются успешно.

Однако, когда я попытался ввести другую сущность, invoice , он выдает ошибку в Run build и Java-компиляторе во время Make. Я попытался решить проблему путем переноса базы данных в соответствии с рекомендациями Суслова (https://medium.com/@kirillsuslov/how-to-add-more-that-one-entity-in-room-5cc3743219c0). Несмотря на редактирование, возникают похожие ошибки.

Наконец, я хотел бы знать, как правильно определить более одной таблицы, используя Room. Но, кроме этого, мне также нужно некоторое понимание ошибок. Спасибо за внимание.

Попытка обхода

Согласно Суслову, для введения дополнительных таблиц в базу данных требуется миграция. В источнике также упоминается, что определение миграции следует поместить в наследник RoomDatabase ( POSDatabase ).

static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            database.execSQL("CREATE TABLE IF NOT EXISTS `invoice` (`invoice_id` VARCHAR, "
                    + "`terminal_no` VARCHAR NOT NULL, `cashier_name` TEXT,  PRIMARY KEY(`invoice_id`))");
        }
    };

MIGRATION_1_2 затем включается во время вызова:

Room.databaseBuilder(context.getApplicationContext(),
                                    POSDatabase.class,
                                 "pos_database").addMigrations(MIGRATION_1_2).build();

Item.java

package com.example.qrreceipt;

import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

@Entity(tableName = "item")
public class Item {
    @PrimaryKey
    @NonNull
    @ColumnInfo(name = "item_id")
    private String item_id;

    @ColumnInfo(name = "description")
    private String description;

    @ColumnInfo(name = "price")
    private double price;

    public Item() { }

    @NonNull
    public String getItem_id() {
        return item_id;
    }

    public String getDescription() {
        return description;
    }

    public double getPrice() {
        return price;
    }

    public void setItem_id(@NonNull String item_id) {
        this.item_id = item_id;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}
* * ItemDao.java тысяча сорок-девять
package com.example.qrreceipt;

import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;

import java.util.List;

@Dao
public interface ItemDao {
    @Insert
    void insertItem(Item item);

    @Update
    void updateItem(Item item);

    @Query("SELECT * FROM item WHERE item_id = :item_id")
    List<Item> findItem(String item_id);

    @Query("SELECT * FROM item")
    List<Item> getAllItems();

    @Query("DELETE FROM item WHERE item_id = :item_id")
    void deleteItem(String item_id);
}

POSDatabase.java

package com.example.qrreceipt;

import android.content.Context;

import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;

@Database(entities = {Item.class, Invoice.class}, version = 2, exportSchema = false)
public abstract class POSDatabase extends RoomDatabase {
    public abstract ItemDao getItemDAO();
    public abstract InvoiceDao getInvoiceDAO();

    private static POSDatabase INSTANCE;

    static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            database.execSQL("CREATE TABLE IF NOT EXISTS `invoice` (`invoice_id` VARCHAR, "
                    + "`terminal_no` VARCHAR NOT NULL, `cashier_name` TEXT,  PRIMARY KEY(`invoice_id`))");
        }
    };

    static POSDatabase getDatabase(final Context context) {
        if (INSTANCE == null) {
            synchronized (POSDatabase.class) {
                if (INSTANCE == null) {
                    INSTANCE =
                            Room.databaseBuilder(context.getApplicationContext(),
                                    POSDatabase.class,
                                 "pos_database").addMigrations(MIGRATION_1_2).build();

                }
            }
        }
        return INSTANCE;
    }
}

Invoice.java

package com.example.qrreceipt;

import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

@Entity(tableName = "invoice")
public class Invoice {
    @PrimaryKey
    @NonNull
    @ColumnInfo(name = "invoice_id")
    private String invoice_id;

    //private Date date;

    @ColumnInfo(name = "terminal_no")
    private String terminal_no;

    @ColumnInfo(name = "cashier_name")
    private String cashier_name;

    public Invoice() { }

    @NonNull
    public String getInvoice_id() {
        return invoice_id;
    }

    public String getTerminal_no() {
        return terminal_no;
    }

    public String getCashier_name() {
        return cashier_name;
    }

    public void setInvoice_id(@NonNull String invoice_id) {
        this.invoice_id = invoice_id;
    }

    public void setTerminal_no(String terminal_no) {
        this.terminal_no = terminal_no;
    }

    public void setCashier_name(String cashier_name) {
        this.cashier_name = cashier_name;
    }
}

InvoiceDao.java

package com.example.qrreceipt;

import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;

import java.util.List;

@Dao
public interface InvoiceDao {
    @Insert
    void insertInvoice(Invoice invoice);

    @Update
    void updateInvoice(Invoice invoice);

    @Query("SELECT * FROM invoice WHERE invoice_id = :invoice_id")
    List<Item> findInvoice(String invoice_id);

    @Query("SELECT * FROM invoice")
    List<Item> getAllInvoices();

    @Query("DELETE FROM invoice WHERE invoice_id = :invoice_id")
    void deleteInvoice(String invoice_id);
}

Выполнить сборку> Выполнить задачи>: app: compileDebugJavaWithJavac

org.gradle.api.tasks.TaskExecutionException: выполнение задачи не выполнено ': Приложение: compileDebugJavaWithJavac. в org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute (ExecuteActionsTaskExecuter.java:95) в org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute (ResolveTaskOutputCachingStateExecuter.java:91) в org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute (ValidatingTaskExecuter.java:57) в org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute (SkipEmptySourceFilesTaskExecuter.java:119) в org.gradle.api.internal.tasks.execution.ResolvePreviousStateExecuter.execute (ResolvePreviousStateExecuter.java:43) в org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute (CleanupStaleOutputsExecuter.java:93) в org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute (FinalizePropertiesTaskExecuter.java:45) в org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute (ResolveTaskArtifactStateTaskExecuter.java:94) в org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute (SkipTaskWithNoActionsExecuter.java:56) в org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute (SkipOnlyIfTaskExecuter.java:55) в org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute (CatchExceptionTaskExecuter.java:36) в org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter $ 1.executeTask (EventFiringTaskExecuter.java:67) в org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter $ 1.call (EventFiringTaskExecuter.java:52) в org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter $ 1.call (EventFiringTaskExecuter.java:49) в org.gradle.internal.operations.DefaultBuildOperationExecutor $ CallableBuildOperationWorker.execute (DefaultBuildOperationExecutor.java:315) вorg.gradle.internal.operations.DefaultBuildOperationExecutor $ CallableBuildOperationWorker.execute (DefaultBuildOperationExecutor.java:305) в org.gradle.internal.operations.DefaultBuildOperationExecutor.execute (DefaultBuildOperationExecutor.java:175) в org.gradle.internal.operations.DefaultBuildOperationExecutor.call (DefaultBuildOperationExecutor.java:101) в org.gradle.internal.operations.DelegatingBuildOperationExecutor.call (DelegatingBuildOperationExecutor.java:36) в org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute (EventFiringTaskExecuter.java:49) в org.gradle.execution.plan.LocalTaskNodeExecutor.execute (LocalTaskNodeExecutor.java:43) в org.gradle.execution.taskgraph.DefaultTaskExecutionGraph $ InvokeNodeExecutorsAction.execute (DefaultTaskExecutionGraph.java:355) в org.gradle.execution.taskgraph.DefaultTaskExecutionGraph $ InvokeNodeExecutorsAction.execute (DefaultTaskExecutionGraph.java:343) в org.gradle.execution.taskgraph.DefaultTaskExecutionGraph $ BuildOperationAwareExecutionAction.execute (DefaultTaskExecutionGraph.java:336) в org.gradle.execution.taskgraph.DefaultTaskExecutionGraph $ BuildOperationAwareExecutionAction.execute (DefaultTaskExecutionGraph.java:322) в org.gradle.execution.plan.DefaultPlanExecutor $ ExecutorWorker $ 1.execute (DefaultPlanExecutor.java:134) в org.gradle.execution.plan.DefaultPlanExecutor $ ExecutorWorker $ 1.execute (DefaultPlanExecutor.java:129) в org.gradle.execution.plan.DefaultPlanExecutor $ ExecutorWorker.execute (DefaultPlanExecutor.java:202) в org.gradle.execution.plan.DefaultPlanExecutor $ ExecutorWorker.executeNextNode (DefaultPlanExecutor.java:193) в org.gradle.execution.plan.DefaultPlanExecutor $ ExecutorWorker.run (DefaultPlanExecutor.java:129) в org.gradle.internal.concurrent.ExecutorPolicy $ CatchAndRecordFailures.onExecute (ExecutorPolicy.java:63) в org.gradle.internal.concurrent.ManagedExecutorImpl $ 1.run (ManagedExecutorImpl.java:46) в java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142) в java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:617) в org.gradle.internal.concurrent.ThreadFactoryImpl $ ManagedThreadRunnable.run (ThreadFactoryImpl.java:55) at java.lang.Thread.run (Thread.java:745) Причина: org.gradle.api.internal.tasks.compile.CompilationFailedException: Компиляция не удалась; см. вывод ошибки компилятора для деталей. в org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute (JdkJavaCompiler.java:52) в org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute (JdkJavaCompiler.java:36) в org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.delegateAndHandleErrors (NormalizingJavaCompiler.java:100) в org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute (NormalizingJavaCompiler.java:52) в org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute (NormalizingJavaCompiler.java:38) в org.gradle.api.internal.tasks.compile.AnnotationProcessorDiscoveringCompiler.execute (AnnotationProcessorDiscoveringCompiler.java:51) в org.gradle.api.internal.tasks.compile.AnnotationProcessorDiscoveringCompiler.execute (AnnotationProcessorDiscoveringCompiler.java:37) в org.gradle.api.internal.tasks.compile.CleaningJavaCompilerSupport.execute (CleaningJavaCompilerSupport.java:39) в org.gradle.api.internal.tasks.compile.incremental.IncrementalCompilerFactory $ 2.execute (IncrementalCompilerFactory.java:110) в org.gradle.api.internal.tasks.compile.incremental.IncrementalCompilerFactory $ 2.execute (IncrementalCompilerFactory.java:106) в org.gradle.api.internal.tasks.compile.incremental.IncrementalResultStoringCompiler.execute (IncrementalResultStoringCompiler.java:59) в org.gradle.api.internal.tasks.compile.incremental.IncrementalResultStoringCompiler.execute (IncrementalResultStoringCompiler.java:43)по адресу org.gradle.api.internal.tasks.compile.CompileJavaBuildOperationReportingCompiler $ 2.call (CompileJavaBuildOperationReportingCompiler.java:59) по адресу org.gradle.api.internal.tasks.compile.CompileJavaBuildOperationReile $ Компиляция репортажа.gradle.internal.сgradle.api.internal.tasks.compile.CompileJavaBuildOperationReportingCompiler.execute (CompileJavaBuildOperationReportingCompiler.java:51) в org.gradle.api.tasks.compile.JavaCompile.performCompilation (JavaCompile.java:154) в org.gradle.api.tasks.compile.JavaCompile.compile (JavaCompile.java:12).android.build.gradle.tasks.AndroidJavaCompile.compile (AndroidJavaCompile.kt: 214) в sun.reflect.NativeMethodAccessorImpl.invoke0 (нативный метод) в sun.reflect.NativeMethodAccessorImpl.invoke (NativeFmp.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) в java.lang.reflect.Method.invoke (Method.java:498) в org.gradle.internal.reflect.JavaMethod.invoke (JavaMethod).gradle.api.internal.project.taskfactory.IncrementalTaskAction.doExecute (IncrementalTaskAction.java:47) в org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute (StandardTaskAction.java:dle.ag.g. org. org. org.internal.project.taskfactory.StandardTaskAction.execute (StandardTaskAction.java:28) в org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter $ 2.run (ExecuteActionsTaskExecuter.java:284) в org.gradle..java: 293) в org.gradle.internal.operations.DefaultBuildOperationExecutor.execute (DefaultBuildOperationExecutor.java:175) в org.gradle.internal.operations.DefaultBuildOperationExecutor.run (DefaultBuildOperationExecutor.jternal:gra. orternal.gra.grag или в .in)operations.DelegatingBuildOperationExecutor.run (DelegatingBuildOperationExecutor.java:31) в org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction (ExecuteActionsTaskExecuter.java:273.exas.ecute.executeActions (ExecuteActionsTaskExecuter.java:258) в org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access $ 200 (ExecuteActionsTaskExecuter.java:67) в org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter $ TaskExecution.execute (ExecuteActionsTaskExecuter.java:145) в org.gradle.internal.exte..execute (ExecuteStep.java:49) в org.gradle.internal.execution.impl.steps.CancelExecutionStep.execute (CancelExecutionStep.java:34) в org.gradle.internal.execution.impl.steps.TimeoutStep.executeithoutSout.java: 69) в org.gradle.internal.execution.impl.steps.TimeoutStep.execute (TimeoutStep.java:49) в org.gradle.internal.execution.impl.steps.CatchExceptionStep.execute (CatchExceptionStep.java:33) в org.gradle.internal.execution.impl.steps.CreateOutputsStep.execute (CreateOutputsStep.java:50) вorg.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute (SnapshotOutputStep.java:43) в org.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute (SnapshotOutputStep.java:29.)internal.execution.impl.steps.CacheStep.executeWithoutCache (CacheStep.java:134) в org.gradle.internal.execution.impl.steps.CacheStep.lambda $ выполнить $ 3 (CacheStep.java:83) в java.util.Optional.orElseGet (Optional.java:267) в org.gradle.internal.execution.impl.steps.CacheStep.execute (CacheStep.java:82) в org.gradle.internal.execution.impl.steps.CacheStep.execute (CacheStep.java: 36) в org.gradle.internal.execution.impl.steps.PrepareCachingStep.execute (PrepareCachingStep.java:33) в org.gradle.internal.execution.impl.steps.StoreSnapshotsStep.execute (StoreSnapshotsS38).грadle.internal.execution.impl.steps.SkipUpToDateStep.lambda $ execute $ 0 (SkipUpToDateStep.java:89) в java.util.Optional.map (Optional.java:215) в org.gradle.internal.execution.impl.steps«.java: 34) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute (ExecuteActionsTaskExecuter.java:91) ... еще 35

Компилятор Java: (2 ошибки, 2предупреждения)

Предупреждение. Запрос возвращает несколько столбцов [invoice_id, Terminal_no, cashier_name], которые не используются com.example.qrreceipt.Item.Вы можете использовать аннотацию @ColumnInfo в полях, чтобы указать отображение.com.example.qrreceipt.Item имеет несколько полей [item_id, description, price], которые не возвращаются запросом.Если они не должны быть прочитаны из результата, вы можете пометить их аннотацией @Ignore.Вы можете подавить это предупреждение, аннотируя метод с помощью @SuppressWarnings (RoomWarnings.CURSOR_MISMATCH).Столбцы, возвращаемые запросом: invoice_id, terminal_no, cashier_name.Поля в com.example.qrreceipt.Item: item_id, description, price.

Ошибка: столбцы, возвращаемые запросом, не имеют полей [item_id, price] в com.example.qrreceipt.Item, хотяони аннотируются как ненулевые или примитивные.Столбцы, возвращаемые запросом: [invoice_id, Terminal_no, cashier_name]

Предупреждение. Запрос возвращает некоторые столбцы [invoice_id, Terminal_no, cashier_name], которые не используются com.example.qrreceipt.Item.Вы можете использовать аннотацию @ColumnInfo в полях, чтобы указать отображение.com.example.qrreceipt.Item имеет несколько полей [item_id, description, price], которые не возвращаются запросом.Если они не должны быть прочитаны из результата, вы можете пометить их аннотацией @Ignore.Вы можете подавить это предупреждение, аннотируя метод с помощью @SuppressWarnings (RoomWarnings.CURSOR_MISMATCH).Столбцы, возвращаемые запросом: invoice_id, terminal_no, cashier_name.Поля в com.example.qrreceipt.Item: item_id, описание, цена.

Ошибка: ошибка: столбцы, возвращаемые запросом, не имеют полей [item_id, price] в com.example.qrreceipt.Itemдаже если они аннотированы как ненулевые или примитивные.Столбцы, возвращаемые запросом: [invoice_id, Terminal_no, cashier_name]

1 Ответ

0 голосов
/ 07 июля 2019

Первый выпуск

Ваша текущая проблема заключается в том, что вы пытаетесь получить элементы из таблицы счетов-фактур.

Вот что говорит следующее: -

Ошибка: столбцы, возвращаемые запросом, не имеют полей [item_id, price] в com.example.qrreceipt.Item, даже если они аннотируется как ненулевое или примитивное. Столбцы, возвращаемые запросом: [Invoice_id, terminal_no, cashier_name]

Чтобы исправить эту проблему, измените InvoiceDao на использование: -

@Query("SELECT * FROM invoice WHERE invoice_id = :invoice_id")
List<Invoice> findInvoice(String invoice_id);


@Query("SELECT * FROM invoice")
List<Invoice> getAllInvoices();

(т.е. вернуть List<Invoice> вместо List<Item>)

Другие вопросы

После исправления вышеизложенного вы можете столкнуться с проблемами из-за того, что определение таблицы не соответствует сущности.

В том: -

  1. У вас есть @ NonNull для invoice_id , но у вас нет NOT NULL в SQL (они должны совпадать / дополнять друг друга).
  2. У вас есть NOT NULL , закодированный в SQL для terminal_no, но не имеет @NonNull в Invoice @ Dao (опять же они должны дополнять друг друга)
  3. У вас есть VARCHAR, закодированный в SQL как для invoice_id , так и terminal_no , у вас не может быть VARCHAR тип столбца ДОЛЖЕН быть TEXT ( вы весьма ограничены типами столбцов, которые могут быть указаны при использовании комнаты).

Использование: -

database.execSQL("CREATE TABLE IF NOT EXISTS `invoice` (`invoice_id` TEXT NOT NULL, "
                + "`terminal_no` TEXT NOT NULL, `cashier_name` TEXT,  PRIMARY KEY(`invoice_id`))");

вместе с: -

@Entity(tableName = "invoice")
public class Invoice {
    @PrimaryKey
    @NonNull
    @ColumnInfo(name = "invoice_id")
    private String invoice_id;

    //private Date date;

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

    @ColumnInfo(name = "cashier_name")
    private String cashier_name;

    public Invoice() { }

    @NonNull
    public String getInvoice_id() {
        return invoice_id;
    }

    public String getTerminal_no() {
        return terminal_no;
    }

    public String getCashier_name() {
        return cashier_name;
    }

    public void setInvoice_id(@NonNull String invoice_id) {
        this.invoice_id = invoice_id;
    }

    public void setTerminal_no(String terminal_no) {
        this.terminal_no = terminal_no;
    }

    public void setCashier_name(String cashier_name) {
        this.cashier_name = cashier_name;
    }
}

Должно работать.

...