javahibernateswingjpabeans-binding

Java JPA, Swing and Beans Binding: Changes to a OneToMany collection in entity not immediately reflected in GUI


I am trying to learn JPA with Hibernate and binding it to a GUI built in Netbeans with Beans Binding. It is a application listing dogs. Each dog can have one to many puppies. You can add and delete dogs, and for each dog you can add and delete puppies.

The dogs are displayed in a JList, when the user selects a dog its properties is shown in JTextFileds and its puppies are shown in a JTable. Adding/deleting dogs works fine because the list containing the Dog instances are Observable.

The Dogs puppies are maintained in a Collection in the Dog class with getter and setter:

@OneToMany(targetEntity = Puppie.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "dog_id")
private Collection<Puppie> puppies;

public Collection<Puppie> getPuppies() {
    if (puppies == null) {
        puppies = new ArrayList<Puppie>();
    }
    return puppies;
}

public void setPuppies(Collection<Puppie> puppies) {
    Collection<Puppie> oldPuppies = this.puppies;
    this.puppies = puppies;
    changeSupport.firePropertyChange("puppies", oldPuppies, puppies);
}

When I add a puppie to the dog selected in the JList it is not reflected in the JTable immediately. I have to select another dog and then reselect the dog I added the puppy to to make it show up in the JTable. I am using the following add/delete puppie methods in the Dog class:

public void addPuppie(Puppie puppie) {
    getPuppies().add(puppie);
}

public void deletePuppie(Puppie puppie) {
    getPuppies().remove(puppie);
}

The JTable is bound to the JList (and not the dogs list) with ${selectedElement.puppies} as binding expression.

The setters in the Puppie class fire property changes when properties are set.

This is the code for adding a puppie:

@Action
public void addPuppy() {
    Puppie p = new Puppie();
    p.setName("new puppie");
    entityManager.persist(p);

    int selectedIndex = dogsJList.getSelectedIndex();
    Dog d = (Dog) dogList.get(selectedIndex);
    d.addPuppie(p);
    setSaveNeeded(true);
}

Any help would be greatly appreciated! Let me know if you need more information.

Regards, Henrik


Solution

  • It seems that the JTable isn't automatically updated. By looking at the Netbeans generated code it clears the selection in the JList and then reselects the entry, and thereby the JTable get refreshed.

    Since Netbeans generates this code I'm assuming that the second JTable can not be automatically updated with Bean Binding and that one have to clear the selection in the JList and then reselects the entry.