# Datenbank editierbach machen in JTable



## maGG (14. Jun 2019)

Ich habe mach mein ein neues Thema auf, das alte passt nicht mehr unbedingt und es ist inzwischen ziemlich lang.
Hier der Link zum anderen Thema: https://www.java-forum.org/thema/2-combobox-en.184473/page-11

Ich habe aktuell folgendes Problem: Das Editieren der Datenbank funktioniert vom Prinzp eigentlich schon, jedoch hatte ich letztens immer NullPointerExceptions. Ich habe jetzt sozusagen den Übeltäter gefunde und es müsste etwas mit meinem Listener bzw. mit meinm fireEvet etc. zu tun haben. Wenn ich nämlich diesen auskommentiere kommt keine NPS, jedoch wird nach drücken des Buttons dann auch nicht die jTable aktualisiert.

Mein JFrame ist jetzt aufgeteilt in mehrere jPanels und ich habe dazu eine Repository sowie ModelClass:

Code in BranchModel:


```
public void update(Branch branch) {
      try {
        branches.updateBranch(branch);
        int ix = data.indexOf(branch);
        fireContentsChanged(ix,ix);
        fireTableRowsUpdated(ix, ix);
      } catch(SQLException ex) {
        ex.printStackTrace();
      }
    }

    protected void fireContentsChanged(int index0, int index1){
        ListDataEvent event = new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index0, index1);
        for (ListDataListener l : listeners.getListeners(ListDataListener.class)) {
            l.contentsChanged(event);
        }
    }
```

Code in BranchRepository:


```
//...
    fireUpdated(branch);
    //...

    private void fireUpdated(Branch branch) {
        fireEvent(new RepositoryEvent<>(RepositoryEvent.Type.UPDATED, branch));
    }
 
    private void fireEvent(RepositoryEvent<Branch> event) {
        Iterator<WeakReference<RepositoryListener<Branch>>> it = listeners.iterator();
        while (it.hasNext()) {
            WeakReference<RepositoryListener<Branch>> ref = it.next();
            RepositoryListener<Branch> listener = ref.get();
            if (listener != null) {
                listener.eventOccured(event);        
            } else {
                it.remove();
            }
        }
    }
```

Code in PanelBranch:


```
//...
private void update(Branch branch) {
    //...
    branchModel.update(current);
    //...
}
//...
```

Code in RepositoryEvent:


```
public class RepositoryEvent<T> {
      public enum Type {
        ADDED, REMOVED, UPDATED
      };

      private final T value;
      private final Type type;

      public RepositoryEvent(Type type, T value) {
        this.type = type;
        this.value = value;
      }

      public Type getType() {
        return type;
      }

      public T getValue() {
        return vaule;
      }
    }
```

Code RepositoryListener:


```
public interface RepositoryListener<T> {
  void eventOccured(RepositoryEvent<T> event>;
}
```


----------



## mihe7 (14. Jun 2019)

Das Problem ist, Deine Aussage bzgl. der Events passt nicht zum Stacktrace:

```
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at org.sqlite.core.DB.prepare(DB.java:222)
    at org.sqlite.core.CorePreparedStatement.<init>(CorePreparedStatement.java:41)
    at org.sqlite.jdbc3.JDBC3PreparedStatement.<init>(JDBC3PreparedStatement.java:30)
    at org.sqlite.jdbc4.JDBC4PreparedStatement.<init>(JDBC4PreparedStatement.java:19)
    at org.sqlite.jdbc4.JDBC4Connection.prepareStatement(JDBC4Connection.java:48)
    at org.sqlite.jdbc3.JDBC3Connection.prepareStatement(JDBC3Connection.java:263)
    at org.sqlite.jdbc3.JDBC3Connection.prepareStatement(JDBC3Connection.java:235)
    at RepositoryClasses.BranchRepository.updateBranch(BranchRepository.java:106)
    at ModelClasses.BranchModel.update(BranchModel.java:64)
    at UserInterface.PanelBranches.update(PanelBranches.java:153)
    at UserInterface.PanelBranches.jButtonUpdateBranchActionPerformed(PanelBranches.java:450)
```
[/code]
Was steht in BranchRepository, Zeile 106?


----------



## maGG (14. Jun 2019)

Hmm also mein aktueller StackTrace sieht so aus:


```
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at org.sqlite.core.DB.prepare(DB.java:222)
    at org.sqlite.core.CorePreparedStatement.<init>(CorePreparedStatement.java:41)
    at org.sqlite.jdbc3.JDBC3PreparedStatement.<init>(JDBC3PreparedStatement.java:30)
    at org.sqlite.jdbc4.JDBC4PreparedStatement.<init>(JDBC4PreparedStatement.java:19)
    at org.sqlite.jdbc4.JDBC4Connection.prepareStatement(JDBC4Connection.java:48)
    at org.sqlite.jdbc3.JDBC3Connection.prepareStatement(JDBC3Connection.java:263)
    at org.sqlite.jdbc3.JDBC3Connection.prepareStatement(JDBC3Connection.java:235)
    at RepositoryClasses.BranchRepository.updateBranch(BranchRepository.java:106)
    at ModelClasses.BranchModel.update(BranchModel.java:64)
    at UserInterface.PanelBranches.update(PanelBranches.java:153)
    at UserInterface.PanelBranches.jButtonUpdateBranchActionPerformed(PanelBranches.java:450)
    at UserInterface.PanelBranches.access$000(PanelBranches.java:19)
    at UserInterface.PanelBranches$1.actionPerformed(PanelBranches.java:266)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6533)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    at java.awt.Component.processEvent(Component.java:6298)
    at java.awt.Container.processEvent(Container.java:2236)
    at java.awt.Component.dispatchEventImpl(Component.java:4889)
    at java.awt.Container.dispatchEventImpl(Container.java:2294)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
    at java.awt.Container.dispatchEventImpl(Container.java:2280)
    at java.awt.Window.dispatchEventImpl(Window.java:2746)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.awt.EventQueue$4.run(EventQueue.java:729)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
```

In der Zeile 106 steht das hier: 
	
	
	
	





```
try(PreparedStatement pst = conn.prepareStatement(sql)) {
```

Also im Moment ist es so: Ich klicke auf den ein Wert in der Tabelle, dann ändere ich einen Wert in einen der Textfelder und drücke auf den Button. Danach kommt die NPE, wenn ich danach nochmal auf die Tabelle klicke hat sich der Wert geändert und wird so angezeigt. Auf der Tabelle ist ja eine Listener drauf, daher meine Vermutung, dass es an den Event Kram liegt, denn die Aktualisierung der Tabelle wird beim Aufruf des Buttons auch nicht angezeigt.


----------



## kneitzel (15. Jun 2019)

Was ist denn in sql? Ist das gesetzt?


----------



## maGG (15. Jun 2019)

Code in BranchRepository zum Update:


```
public class BranchRepository {
    
    private static final EnumMap<Location, String> LOCATION = new EnumMap<>(Location.class);
    
    private static final EnumMap<Location, String> UPDATE = new EnumMap<>(Location.class);
    
        LOCATION.put(Location.DOMESTIC,
                "SELECT * FROM Filialen_Deutschland");
        LOCATION.put(Location.FOREIGN,
                "SELECT * FROM Filialen_Ausland");
        UPDATE.put(Location.DOMESTIC,
                "UPDATE Filialen_Deutschland SET id=?, LABEL=?, STRASZE=?, PLZ_ORT=?, ORT=?, TEL_LAND=?, TEL_ANFANG_INT=?,"
                + "TEL_ANFANG_TXT=?, TEL_ENDE_DEFAULT=?, FAX_ANFANG_TXT=?, FAX_ENDE_TXT=? WHERE id=?");
        UPDATE.put(Location.FOREIGN,
                "UPDATE Filialen_Ausland SET id=?, LABEL=?, STRASZE=?, PLZ_ORT=?, ORT=?,TEL_LAND=?, TEL_ANFANG_INT=?, "
                + "TEL_ANFANG_TXT=?, TEL_ENDE_DEFAULT=?, FAX_ANFANG_TXT=?, FAX_ENDE_TXT=? WHERE id=?");
        }
    private Connection conn;
    
    public BranchRepository() {
        this.conn = null;
    }
    
    public BranchRepository(Connection conn) { //conn wird beim Aufruf des Panels eingesetzt
        this.conn = conn;
    }

    public void updateBranch(Branch branch) throws SQLException {
        Location where = branch.getLocation();
        String sql = UPDATE.get(where);
        try(PreparedStatement pst = conn.prepareStatement(sql)) { 
            pst.setInt(1, branch.getId()); //id
            pst.setString(2, branch.getLabel()); //LABEL
            pst.setString(3, branch.getStrasze()); //STRASZE
            pst.setString(4, branch.getPlzort()); //PLZ_ORT
            pst.setString(5, branch.getOrt()); //ORT
            pst.setInt(6, branch.getVorwahl()); //TEL_LAND
            pst.setLong(7, branch.getTelStartNum()); //TEL_ANFANG_INT
            pst.setString(8, branch.getFaxStartTxt()); //TEL_ANFANG_TXT
            pst.setInt(9, branch.getTelEndDefault());
            pst.setString(10, branch.getFaxStartTxt()); //FAX_ANFANG_TXT
            if(branch.getFaxEndTxt().equals("")) {
                pst.setObject(11, null);
            }else{
                pst.setString(11, branch.getFaxEndTxt()); //FAX_ENDE_TXT
            }
            pst.setInt(12, branch.getId()); //id
            pst.executeUpdate();
            fireUpdated(branch);
        }   
    }

}
```


----------



## mihe7 (15. Jun 2019)

Bau mal ein:

```
public void updateBranch(Branch branch) throws SQLException {
        Location where = branch.getLocation();
        String sql = UPDATE.get(where);
        System.out.println("sql: " + sql);
        System.out.println("where: " + where);
        ...
```


----------



## maGG (15. Jun 2019)

da kommt jetzt das hier:

```
Updating property file: C:\Users\david\Desktop\Signatur\build\built-jar.properties
Compiling 1 source file to C:\Users\david\Desktop\Signatur\build\classes
compile-single:
run-single:
java.lang.OutOfMemoryError
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 48016 bytes for Chunk::new
# An error report file with more information is saved as:
# C:\Users\david\Desktop\Signatur\hs_err_pid10088.log
#
# Compiler replay data is saved as:
# C:\Users\david\Desktop\Signatur\replay_pid10088.log
C:\Users\david\Desktop\Signatur\nbproject\build-impl.xml:1051: The following error occurred while executing this line:
C:\Users\david\Desktop\Signatur\nbproject\build-impl.xml:805: Java returned: 1
BUILD FAILED (total time: 15 seconds)
```

Ok, jetzt ging es doch auf einmal........
kommt das hier:

sql: null
where: null

Und die Filiale wird trotzdem aktualisiert ... genial!


----------



## mihe7 (15. Jun 2019)

maGG hat gesagt.:


> Und die Filiale wird trotzdem aktualisiert ... genial!


lol - das liegt vielleicht daran, dass das Ding doppelt aufgerufen wird: einmal mit null und einmal mit dem richtigen Wert. Fang den null-Fall mal ab und schau, ob die Filiale immer noch aktualisiert wird (if (where == null) return)


----------



## maGG (15. Jun 2019)

wird immer noch aktualisiert :'D

gut, jetzt bekomme ich meine printLines nicht mehr mit null, aber die Filiale wird aktualisiert, ja. Die NPE kommt jetzt auch nicht mehr. Habe mal nach der Methode "updateBranch" gesucht, aber diese ist eigentlich nur in der Klasse BranchRepository drin. In BranchModel habe ich meine Methode ja "update" genannt, kann es daran liegen? Muss man da vielleicht ein override oder sowas machen?


----------



## mihe7 (16. Jun 2019)

maGG hat gesagt.:


> Habe mal nach der Methode "updateBranch" gesucht, aber diese ist eigentlich nur in der Klasse BranchRepository drin. In BranchModel habe ich meine Methode ja "update" genannt, kann es daran liegen? Muss man da vielleicht ein override oder sowas machen?


Ich hab den Code nicht mehr im Kopf aber es sollte keine Rolle spielen, denn das sind zwei verschiedene Dinge. 

Du müsstest Dir den Code anschauen, der ab dem Klick abläuft. Irgendwo scheint Unsinn weitergegeben zu werden.


----------



## maGG (16. Jun 2019)

Wenn ich die Methoden eindeutig benenne kommt jetzt das hier:


```
Error occurred during initialization of VM
Could not reserve enough space for object heap
C:\Users\david\Desktop\Signatur\nbproject\build-impl.xml:1051: The following error occurred while executing this line:
C:\Users\david\Desktop\Signatur\nbproject\build-impl.xml:805: Java returned: 1
BUILD FAILED (total time: 4 seconds)
```

Wenn ich sie uneindeutig belasse scheint es irgendwie zu gehen ... das kann doch nicht sein. Ich habe doch einfach nur dein Code genommen und ihn angepasst. Wieso ist der Mist so kompliziert.... glaub der Compiler ist zu dumm dafür , der Code stimmt so wie er ist, bin ihn schon gefühlt 100 Mal durchgegangen.


----------



## mihe7 (17. Jun 2019)

maGG hat gesagt.:


> Error occurred during initialization of VM Could not reserve enough space for object heap


Das liegt nicht an Deinem Programm, sondern daran, dass nicht genügend RAM für die JVM reserviert werden kann.


----------



## maGG (17. Jun 2019)

Hmm da ich in Java ja immer eine Referenz aus der Klasse brauche, um eine Methode aus eine anderen Klasse aufzurufen, kann es eigentlich nicht zu Overloading kommen. Mit der Verzweigung, die du mir empfohlen hast geht es komischerweise. Ich weiß aber wirklich nicht warum, weil wenn where null ist dürfte der Rest der Methode doch eigentlich gar nicht mehr ausgeführt werden, oder?

Eine Sache wird jetzt jedoch noch angezeigt, und zwar folgendes:


```
BranchRepository.java.70: warning [unchecked] unchecked call to WeakReference(T) as a member of the raw typ WeakReference.add(new WeakReference(listener));
pe-variable:
ect declared in class WeakReference

BranchRepository.java.74: warning [unchecked] unchecked call to WeakReference(T) as a member of the raw typ WeakReference.removenew WeakReference(listener));
pe-variable:
ect declared in class WeakReference
```

in Zeile 70 steht:

```
public void addListener(RepositoryListener<Branch> listener) {
listeners.add(new WeakReference(listener));
}
```

in Zeile 74 steht:

```
public void removeListener(RepositoryListener<Branch> listener) {
listeners.remove(new WeakReference(listener));
}
```


----------



## mihe7 (17. Jun 2019)

Bzgl. der WeakReference mach mal ein `new WeakReference<>(listener)` draus.



maGG hat gesagt.:


> Mit der Verzweigung, die du mir empfohlen hast geht es komischerweise. Ich weiß aber wirklich nicht warum, weil wenn where null ist dürfte der Rest der Methode doch eigentlich gar nicht mehr ausgeführt werden, oder?


Nein, wie gesagt: vermutlich wird die Methode doppelt aufgerufen, einmal mit null und einmal mit dem richtigen Wert.


----------

