1

ヒューマンエラー。以下のコードにエラーはありません

モデレーター: これを削除してください。可能であれば、私の評判の 25 を Peter Lawrey に送ってください。ピーター ローリーは、ログ データの厚いスタックを読んでさえも、私を大いに助けてくれました。ありがとう!

こんにちは、シリアル化可能なデータベースに問題があります。

プログラムを (ログアウト ボタンを使用して) 閉じた後、データベースは保存されるはずです。これはコードです:

FileOutputStream f_out = null;
        try {
            f_out = new FileOutputStream("database.data");
            ObjectOutputStream obj_out = new ObjectOutputStream(f_out);
            obj_out.writeObject(database);
            System.out.println("Stored!");

        } catch (Exception ex) {
            Logger.getLogger(BankMainFrameGUI.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        } finally {
            try {
                f_out.close();
            } catch (IOException ex) {
                Logger.getLogger(BankMainFrameGUI.class.getName()).log(Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            }
        }
        new BankMainFrameGUI();
        this.dispose();

データベースは、ログイン時に次のコードで復元されます。

    try {
        FileInputStream f_in = new FileInputStream("database.data");
        ObjectInputStream obj_in = new ObjectInputStream(f_in);
        database = (BankSystem) obj_in.readObject();
        System.out.println("FOUND!");
    } catch (Exception e) {
        System.out.println("New database!");
        database = new BankSystem();
    }

データベースとそのすべての内部クラスはシリアライズ可能に設定されています。ただし、プログラムを再起動すると、すべてのデータ (クライアント、アカウント、トランザクション) が失われます。ただし、データベースは引き続き「Found!」として検出されます。ステートメントはコンパイラの CLI に表示されますが、「新しいデータベース!」には表示されません。声明。

連結リストと配列リストの両方を使用しました。

どうもありがとう!実行可能なすべてのソリューションを評価します。

ネタバレ: 不必要な情報がたくさんあります

必要に応じて追加情報:

Main BankSystem() constructor + important variables:

public class BankSystem implements Serializable {
    Transaction transactionManager;
    Identity identityManager;
    Account accountManager;
    dayFirstTransaction dayFirstTransactionManager;


    public BankSystem() {
        transactionManager = new Transaction();
        identityManager = new Identity();
        accountManager = new Account();
        dayFirstTransactionManager = new dayFirstTransaction();
    }
...

LinkedList ノードの例:

class Transaction implements Serializable { //Database for TransactionNode
    TransactionNode lastTransaction = null;
    long lastTransactionId = -1;

    //Unchangable location settings defined. Prevents ability to manipulate timestamp by changing computer clock. Acts as a security feature.
    //Timestamps are also finalised to ensure security (prevent manipulation)
    final TimeZone tz = TimeZone.getTimeZone("Singapore");
    final Locale lc = new Locale("en", "SG");
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS EEEE");
    final private Calendar cal = Calendar.getInstance(tz, lc);

    public long newTransaction(dayFirstTransaction dFTM,
            Client identity, AccountNode account, boolean action, long actionAmount, 
            String location, String comments) throws IOException {
        //Setting timings
        long timeMilli = cal.getTimeInMillis();
        String timeStamp = dateFormat.format(cal.getTime());

        TransactionNode previous = lastTransaction;
        TransactionNode previousUserTransaction = account.GetLastTransaction();

        long transactionId = ++lastTransactionId;

        long initialBalance = account.getBalance();
        long finalBalance;
        if(action) {
            finalBalance = initialBalance + actionAmount;
        } else {
            if(initialBalance < actionAmount) throw new IOException("There is not enough funds present in account " + account.accountId + ". \nAvailable balance: $" + account.getBalance());
            finalBalance = initialBalance - actionAmount;
        }

        lastTransaction = new TransactionNode(previous, previousUserTransaction, timeMilli, timeStamp,  
            transactionId, identity, account, action, actionAmount, 
            initialBalance, finalBalance, location, comments);

        dFTM.checkTransaction(lastTransaction);
        account.setLastTransaction(lastTransaction);
        return transactionId;
    }

        public void newTransaction (dayFirstTransaction dFTM, long timeMilli, String timeStamp,  
            Client identity, AccountNode account, boolean action, long actionAmount, 
            long initialBalance, long finalBalance, String location, String comments) throws IOException {

        TransactionNode previous = lastTransaction;
        TransactionNode previousUserTransaction = account.GetLastTransaction();

        long transactionId = ++lastTransactionId;

        lastTransaction = new TransactionNode(previous, previousUserTransaction, timeMilli, timeStamp,  
            transactionId, identity, account, action, actionAmount, 
            initialBalance, finalBalance, location, comments);

        dFTM.checkTransaction(lastTransaction);
        account.setLastTransaction(lastTransaction);
    }
...

そして、このリンクされたリストのノード:

class TransactionNode implements Serializable {
    //Node direction pointers
    final private TransactionNode previous;
    final private TransactionNode previousUserTransaction;

    //Declarations
    //For action:
    final public boolean CREDIT = true;
    final public boolean DEBIT = false;

    //Variables for each transaction
    final public long timeMilli; //Automated. For time comparisons
    final public String timeStamp;//Automated. For user reference
    final public long transactionId; // Automated at Transaction LinkedList
    final public Client identity;
    final public AccountNode account;
    final public boolean action; //true: Credit. false:Debit
    final public long actionAmount;
    final public long initialBalance;
    final public long finalBalance;
    final public String location;
    final public String comments;

    public TransactionNode(TransactionNode previous, TransactionNode previousUserTransaction, long timeMilli, String timeStamp,  
            long transactionId, Client identity, AccountNode account, boolean action, long actionAmount, 
            long initialBalance, long finalBalance, String location, String comments) {
        this.previous = previous;
        this.previousUserTransaction = previousUserTransaction;
        this.timeMilli = timeMilli;
        this.timeStamp = timeStamp;
        this.transactionId = transactionId;
        this.identity = identity;
        this.account = account;
        this.action = action;
        this.actionAmount = actionAmount;
        this.initialBalance = initialBalance;
        this.finalBalance = finalBalance;
        this.location = location;
        this.comments = comments;
    }

    //Getters & setters
    public TransactionNode getPreviousTransaction() {
        return previous;
    }

    public TransactionNode getPreviousUserTransaction() {
        return previousUserTransaction;
    }

}
4

4 に答える 4

1
} catch (Exception e) {
    System.out.println("New database!");
    database = new BankSystem();
}

ここに大きな問題があります。これは、逆シリアル化の例外を処理するためのばかげた方法です。実際の例外をログに記録して中止する代わりに、次のようにします。

  1. 実際の例外を完全に無視します。これは、実際に何がうまくいかなかったかに関する唯一の情報源です。

  2. 何も起こらなかったかのように進みます。

  3. nullデータベースではなく、空のデータベースを使用して続行します。これにより、不思議なゼロ化されたデータベース以外は何も問題がなかったかのように、アプリケーションの残りの部分を続行できます。

私はその例外をまったく捕まえませんでした。main()私はそれをコンストラクター、そしておそらくメソッドさえもずっと泡立たせます。

于 2012-08-21T10:06:54.403 に答える
1

これをトリガーしていませんか?

catch (Exception e) {
   System.out.println("New database!");
   database = new BankSystem();
}

トリガーされていない場合でも、少なくとも上記に関連する例外とスタック トレースを出力します。

また、書き出すファイルが作成中であり、サイズがゼロでないことも確認します。これにより、データが書き込まれている (注意してください - おそらく不完全です) か、読み取られていないかについての指標が得られます。

于 2012-08-21T09:52:16.470 に答える
1

最も考えられる原因は、書き込んだストリームを閉じていないことです。ObjectOutputStream はバッファリングされており、書き込み先のファイルを閉じるのではなく閉じると、すべてのデータが書き込まれず、読み取ろうとすると例外が発生します。

于 2012-08-21T09:54:14.873 に答える
0
  1. ストリームを閉じる
  2. serializable すべてのクラスが、目に見えないいくつかのクラスを実装していることを確認してくださいClientAccountNode
  3. 各例外で printStackTrace() メソッドを使用します。
于 2012-08-21T10:02:19.003 に答える