ObjectDB を使用して一連のデータベースを作成および維持する Java アプリケーションを作成しています。現在、ユーザー名とパスワードの文字列で構成されるユーザー オブジェクトを格納する DB を実装しようとしています。JFrame/swing クラスには、新しいユーザーを作成するためのボタンがあります。このボタンをクリックすると、次のことが起こります。
- データベースの作成 (または接続)
- データベースを検索して、指定されたユーザー名を持つユーザー オブジェクトが存在するかどうかを確認します
- ユーザーが既に存在する場合はダイアログ メッセージを表示し、そうでない場合はユーザーを作成します
ただし、このボタンをクリックすると、クエリ オブジェクトの結果を使用する行に「ユーザーが見つかりません」というエラーが表示されます。空のデータベースがあるためだと確信していますが、プログラムを初めて実行するときにコードを機能させたいので、空のデータベースを処理する必要があります。クエリが最初に実行される前にコードを変更して新しいユーザーを作成しようとしましたが、ボタンがクリックされるたびにコードが希望どおりに機能し、新しいユーザーを作成する必要があるかどうかを検出できます。
検索が機能するように「デフォルト」または「管理者」タイプのユーザーを作成しようとしましたが、これは、プログラムが実行されるたびに繰り返し「デフォルト」ユーザーが作成されることを意味します。これは明らかに望ましくない機能であり、できます。データベースが空かどうかを確認するためのクエリを実行します (そのため、プログラムの最初の実行時にしかデフォルト ユーザーを作成できませんでした)。それが最初に抱えていた問題だからです。
では、ObjectDB の経験がある人なら誰でも、空のデータベースが検索された場合に対処できる方法はありますか?
私のコードの関連部分は次のとおりです。
public class FrameLogIn extends JFrame {
private JPanel contentPane;
private String username;
char[] password;
private static EntityManager em;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
FrameLogIn frame = new FrameLogIn();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public FrameLogIn() {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("user.odb");
em = emf.createEntityManager();
final JTextField txtUsername = new JTextField();
txtUsername.setFont(new Font("Segoe UI Light", Font.PLAIN, 30));
txtUsername.setHorizontalAlignment(SwingConstants.CENTER);
txtUsername.setToolTipText("username");
txtUsername.setText("");
txtUsername.setBounds(220, 30, 177, 52);
contentPane.add(txtUsername);
txtUsername.setColumns(10);
final JPasswordField passwordField = new JPasswordField();
passwordField.setFont(new Font("Tahoma", Font.PLAIN, 30));
passwordField.setHorizontalAlignment(SwingConstants.CENTER);
passwordField.setBounds(220, 93, 177, 52);
contentPane.add(passwordField);
JButton btnNewUser = new JButton("New user");
btnNewUser.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
username = txtUsername.getText();
password = passwordField.getPassword();
System.out.println(username);
TypedQuery<Long> q = em.createQuery(
"SELECT COUNT(u) FROM User u "
+ "WHERE u.name = '" + username + "'", Long.class);
if (q.getSingleResult()>0) {
JOptionPane.showMessageDialog(contentPane.getParent(), "A user with this name already exists.");
} else {
em.getTransaction().begin();
User newUser = new User(username, password.toString());
em.persist(newUser);
em.getTransaction().commit();
JOptionPane.showMessageDialog(contentPane.getParent(), "User created.");
}
}
});
btnNewUser.setFont(new Font("Segoe WP Semibold", Font.PLAIN, 25));
btnNewUser.setBackground(Color.WHITE);
btnNewUser.setBounds(71, 175, 149, 63);
contentPane.add(btnNewUser);
}
}
そしてエラー:
Exception in thread "AWT-EventQueue-0" [ObjectDB 2.5.3_03] SELECT COUNT(u) FROM ==> User <== u WHERE u.name = ''
javax.persistence.PersistenceException
Type User is not found (error 301)
(position 21) at com.objectdb.jpa.JpaQuery.getSingleResult(JpaQuery.java:723)
at sg.FrameLogIn$2.actionPerformed(FrameLogIn.java:113)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: com.objectdb.o.TEX: Type User is not found
at com.objectdb.o.MSG.e(MSG.java:107)
at com.objectdb.o.TRS.g(TRS.java:212)
at com.objectdb.o.SYR.q(SYR.java:259)
at com.objectdb.o.SYR.n(SYR.java:188)
at com.objectdb.o.QRC.<init>(QRC.java:152)
at com.objectdb.o.QRM.U6(QRM.java:250)
at com.objectdb.o.MST.U6(MST.java:933)
at com.objectdb.o.WRA.U6(WRA.java:293)
at com.objectdb.o.WSM.U6(WSM.java:114)
at com.objectdb.o.QRR.g(QRR.java:245)
at com.objectdb.o.QRR.f(QRR.java:154)
at com.objectdb.jpa.JpaQuery.getSingleResult(JpaQuery.java:716)
... 37 more
また、プレーンテキストのパスワードを保存しないという記録についても感謝します。ハッシュ化されたパスワードの実装を開始する前に、基本的なDBを機能させようとしています。