2017-02-12 3 views
0

J'ai un tableau JavaFX simple qui est rempli par une requête de base de données JPA. J'ai une colonne définie comme modifiable et cela fonctionne. Cependant, après qu'une modification est effectuée dans une cellule, elle disparaît dès que je trier ou même naviguer dans le TableView. De même, comment persisteriez-vous ces modifications dans la base de données?Les modifications apportées à la cellule tableview sont perdues

Voici le fichier FXML et son contrôleur:

<?xml version="1.0" encoding="UTF-8"?> 

<?import java.lang.*?> 
<?import java.net.*?> 
<?import java.util.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.control.cell.*?> 
<?import javafx.scene.layout.*?> 

<AnchorPane id="AnchorPane" prefHeight="600.0" prefWidth="800.0" styleClass="mainFxmlClass" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.IXS.synergyixs.ingestor.ViewUsersController"> 
    <stylesheets> 
     <URL value="@/styles/IssueTrackingLite.css" /> 
    </stylesheets> 
    <children> 
     <TableView fx:id="loginsTable" editable="true" prefHeight="593.0" prefWidth="794.0"> 
      <columns> 
       <TableColumn fx:id="idCol" editable="false" text="Id"> 
       </TableColumn> 
       <TableColumn fx:id="loginCol" text="Login"> 
       </TableColumn> 
       <TableColumn fx:id="partyCol" editable="false" text="Party ID"> 
       </TableColumn> 
       <TableColumn fx:id="creatorCol" editable="false" text="Creator ID"> 
       </TableColumn> 
       <TableColumn fx:id="modifierCol" editable="false" text="Modifier ID"> 
       </TableColumn> 
      </columns> 
     </TableView> 
    </children> 
</AnchorPane> 

le contrôleur:

package com.IXS.synergyixs.ingestor; 

import com.IXS.synergyixs.ingestor.data.Usr; 
import java.net.URL; 
import java.util.List; 
import java.util.ResourceBundle; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.control.cell.TextFieldTableCell; 
import javafx.scene.layout.Pane; 
import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.Persistence; 

/** 
* FXML Controller class 
* 
* @author Owner 
*/ 
public class ViewUsersController implements Initializable { 

    public EntityManagerFactory emf = Persistence.createEntityManagerFactory("com.mycompany_SynergyIXS-Ingestor_jar_1.0-SNAPSHOTPU"); 
    public EntityManager em = emf.createEntityManager(); 

    public ObservableList<Usr> tableData; 
    public Usr currentUsr; 
    /** 
    * Initializes the controller class. 
    */ 
    @FXML 
    private Pane rootPane; 
    @FXML 
    private TableView<Usr> loginsTable; 

    @FXML 
    private TableColumn<Usr, Number> idCol; 

    @FXML 
    private TableColumn<Usr, String> loginCol; 

    @FXML 
    private TableColumn<Usr, Number> partyCol; 

    @FXML 
    private TableColumn<Usr, Number> creatorCol; 

    @FXML 
    private TableColumn<Usr, Integer> modifierCol; 

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 

     /* to verify query is returning data 
     for (Usr u : userList) { 
      System.out.println(u.getId() + " " + u.getLogin()); 
     } 
     */ 
     idCol.setCellValueFactory(new PropertyValueFactory<>("id")); 

     loginCol.setCellValueFactory(new PropertyValueFactory<>("login")); 
     loginCol.setCellFactory(TextFieldTableCell.forTableColumn‌()); 

     partyCol.setCellValueFactory(new PropertyValueFactory<>("partyId")); 

     creatorCol.setCellValueFactory(new PropertyValueFactory<>("creatorId")); 

     modifierCol.setCellValueFactory(new PropertyValueFactory<>("modifierId")); 
     updateUserList(); 
     loginsTable.setItems(tableData); 
    } 

    public void updateUserList() { 
     List<Usr> userList = em.createNamedQuery("Usr.findAll").getResultList(); 
     if (tableData == null) { 
      tableData = FXCollections.observableArrayList(userList); 
     } else { 
      tableData.clear(); 
      tableData.addAll(userList); 
     } 
    } 
    /* 
    public void saveUser() 
    { 
     em.getTransaction().begin(); 
     em.persist(currentUsr); 
     em.getTransaction().commit(); 
     updateUserList(); 
    } 
    */ 
}​ 

classe Util:

package com.IXS.synergyixs.ingestor.data; 

import java.io.Serializable; 
import java.math.BigDecimal; 
import java.math.BigInteger; 
import java.util.Date; 
import java.util.List; 
import javax.persistence.Basic; 
import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.NamedQueries; 
import javax.persistence.NamedQuery; 
import javax.persistence.OneToMany; 
import javax.persistence.Table; 
import javax.persistence.Temporal; 
import javax.persistence.TemporalType; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlTransient; 

/** 
* 
* @author Owner 
*/ 
@Entity 
@Table(name = "USR", catalog = "", schema = "ADMIN") 
@XmlRootElement 
@NamedQueries({ 
    @NamedQuery(name = "Usr.findAll", query = "SELECT u FROM Usr u") 
    , @NamedQuery(name = "Usr.findById", query = "SELECT u FROM Usr u WHERE u.id = :id") 
    , @NamedQuery(name = "Usr.findAllLogin", query = "SELECT u.login FROM Usr u") 
    , @NamedQuery(name = "Usr.findByLogin", query = "SELECT u FROM Usr u WHERE u.login = :login") 
    , @NamedQuery(name = "Usr.findByPwd", query = "SELECT u FROM Usr u WHERE u.pwd = :pwd") 
    , @NamedQuery(name = "Usr.findByPartyId", query = "SELECT u FROM Usr u WHERE u.partyId = :partyId") 
    , @NamedQuery(name = "Usr.findByCreatorId", query = "SELECT u FROM Usr u WHERE u.creatorId = :creatorId") 
    , @NamedQuery(name = "Usr.findByCreationDttm", query = "SELECT u FROM Usr u WHERE u.creationDttm = :creationDttm") 
    , @NamedQuery(name = "Usr.findByModifierId", query = "SELECT u FROM Usr u WHERE u.modifierId = :modifierId") 
    , @NamedQuery(name = "Usr.findByModificationDttm", query = "SELECT u FROM Usr u WHERE u.modificationDttm = :modificationDttm")}) 
public class Usr implements Serializable { 

    private static final long serialVersionUID = 1L; 
    // @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation 
    @Id 
    @Basic(optional = false) 
    @Column(name = "ID") 
    private BigDecimal id; 
    @Basic(optional = false) 
    @Column(name = "LOGIN") 
    private String login; 
    @Basic(optional = false) 
    @Column(name = "PWD") 
    private String pwd; 
    @Column(name = "PARTY_ID") 
    private BigInteger partyId; 
    @Basic(optional = false) 
    @Column(name = "CREATOR_ID") 
    private BigInteger creatorId; 
    @Basic(optional = false) 
    @Column(name = "CREATION_DTTM") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date creationDttm; 
    @Basic(optional = false) 
    @Column(name = "MODIFIER_ID") 
    private BigInteger modifierId; 
    @Basic(optional = false) 
    @Column(name = "MODIFICATION_DTTM") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date modificationDttm; 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "usr") 
    private List<UsrAppRole> usrAppRoleList; 

    public Usr() { 
    } 

    public Usr(BigDecimal id) { 
     this.id = id; 
    } 

    public Usr(BigDecimal id, String login, String pwd, BigInteger creatorId, Date creationDttm, BigInteger modifierId, Date modificationDttm) { 
     this.id = id; 
     this.login = login; 
     this.pwd = pwd; 
     this.creatorId = creatorId; 
     this.creationDttm = creationDttm; 
     this.modifierId = modifierId; 
     this.modificationDttm = modificationDttm; 
    } 

    public BigDecimal getId() { 
     return id; 
    } 

    public void setId(BigDecimal id) { 
     this.id = id; 
    } 

    public String getLogin() { 
     return login; 
    } 

    public void setLogin(String login) { 
     this.login = login; 
    } 

    public String getPwd() { 
     return pwd; 
    } 

    public void setPwd(String pwd) { 
     this.pwd = pwd; 
    } 

    public BigInteger getPartyId() { 
     return partyId; 
    } 

    public void setPartyId(BigInteger partyId) { 
     this.partyId = partyId; 
    } 

    public BigInteger getCreatorId() { 
     return creatorId; 
    } 

    public void setCreatorId(BigInteger creatorId) { 
     this.creatorId = creatorId; 
    } 

    public Date getCreationDttm() { 
     return creationDttm; 
    } 

    public void setCreationDttm(Date creationDttm) { 
     this.creationDttm = creationDttm; 
    } 

    public BigInteger getModifierId() { 
     return modifierId; 
    } 

    public void setModifierId(BigInteger modifierId) { 
     this.modifierId = modifierId; 
    } 

    public Date getModificationDttm() { 
     return modificationDttm; 
    } 

    public void setModificationDttm(Date modificationDttm) { 
     this.modificationDttm = modificationDttm; 
    } 

    @XmlTransient 
    public List<UsrAppRole> getUsrAppRoleList() { 
     return usrAppRoleList; 
    } 

    public void setUsrAppRoleList(List<UsrAppRole> usrAppRoleList) { 
     this.usrAppRoleList = usrAppRoleList; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 0; 
     hash += (id != null ? id.hashCode() : 0); 
     return hash; 
    } 

    @Override 
    public boolean equals(Object object) { 
     // TODO: Warning - this method won't work in the case the id fields are not set 
     if (!(object instanceof Usr)) { 
      return false; 
     } 
     Usr other = (Usr) object; 
     if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public String toString() { 
     return "com.mycompany.synergyixs.ingestor.Usr[ id=" + id + " ]"; 
    } 

} 
+0

Publiez la classe 'Usr'. –

+0

Publié, merci. –

+0

de sorte que vous avez débogué aussi loin que où les "changements sont perdus"? dans les appels d'API JPA? ou avant qu'ils arrivent là? –

Répondre

1

Le gestionnaire par défaut onEditCommit suppose le modèle de la table utilise la JavaFX properties pattern (voir TableView documentation, section intitulée "Edi ting "). Puisque votre classe Usr est essentiellement un simple JavaBean, sans méthodes d'accesseur de propriété, le gestionnaire par défaut se réduit à un no-op.

Soit vous devez factoriser votre classe Usr afin qu'il utilise les propriétés JavaFX (voir Using javafx.beans properties in model classes pour une discussion sur l'utilisation des propriétés JavaFX dans des entités JPA), ou définir un gestionnaire onEditCommit sur la colonne:

loginCol.setOnEditCommit(e -> { 
    Usr usr = e.getRowValue(); 
    usr.setLogin(e.getNewValue()); 
}); 

Pour stockez la valeur dans la base de données, utilisez merge(...):

loginCol.setOnEditCommit(e -> { 
    Usr usr = e.getRowValue(); 
    usr.setLogin(e.getNewValue()); 
    // merge change to database: 
    Usr mergedUsr = em.merge(usr); 
    // ensure table has same reference as ORM cache: 
    loginsTable.set(e.getTablePosition().getRow(), mergedUsr); 
}); 
+0

J'ai dû encapsuler la fusion dans une transaction begin et commit et j'ai mis en commentaire le loginsTable.set (... car cela causait une erreur.) Les données sont maintenant persistantes dans la base de données et dans la tableview.Merci pour la référence à la documentation, mon les recherches venaient vides pour cette information. –