Search code examples
sqljsfjpaweld

How to merge records together


i am able to update the database so for each section a user saves it saves there work fine, in the correct column of the database, but what i am now trying to achieve is instead of saving into a new row, check there studentNumber and if it already has a record in the table (which it will have to to get this far ) update the columns to that record rather than starting a new one

how can i do that ?

currently this is my code :

this is the u.i. where they select the value and press submit

                            <p:spinner id="ajaxspinner80-100" value="#{editMarkingBean.markSectionTwo.markSectionTwo}"
                                       stepFactor="1"  min="80" max="100" disabled="#{formBean.number != 8}">
                                <p:ajax update="ajaxspinnervalue" process="@this" />
                            </p:spinner>

the save button

                    <p:commandButton action="#{editMarkingBean.markSectionTwo}" value="#{bundle.buttonSave}" update=":growl" icon="ui-icon-disk"/>

the backing bean is :

@Named(value = "editMarkingBean")
@ViewScoped
public class EditMarkingController {

    private String searchString;
    private String ordering;
    private String criteria;
    private String match;
    private Date today;
    private String caseMatch;
    private int spinnerField;
    private Marking markSectionOne;
    private Marking studentNumber;
    private Marking markSectionTwo;

    private MarkingService markingService;

    private Marking markToEdit;

    @Inject
    private MarkingFacade markingFacade;

    @PostConstruct
    public void init() {
        //this.markToEdit = this.markingFacade.find(studentNumber);
        this.markSectionTwo = new Marking();
    }

    public String markSectionTwo() {
        this.markingFacade.edit(markSectionTwo);
        this.setMessage("Mark Saved");
        markSectionTwo = new Marking();
        this.setMessage("Mark Saved");
        // now navigating to the next page
        return "/lecturer/marking/marking-section-three";
    }

    private void setMessage(String message) {
        FacesContext fc = FacesContext.getCurrentInstance();
        fc.addMessage(null, new FacesMessage(message, ""));
    }

    public Marking getMarkSectionTwo() {
        return markSectionTwo;
    }

    public void setMarkSectionTwo(Marking markSectionTwo) {
        this.markSectionTwo = markSectionTwo;
    }

    public String getSearchString() {
        return searchString;
    }

    public void setSearchString(String searchString) {
        this.searchString = searchString;
    }

    public String getOrdering() {
        return ordering;
    }

    public void setOrdering(String ordering) {
        this.ordering = ordering;
    }

    public String getCriteria() {
        return criteria;
    }

    public void setCriteria(String criteria) {
        this.criteria = criteria;
    }

    public String getMatch() {
        return match;
    }

    public void setMatch(String match) {
        this.match = match;
    }

    public Date getToday() {
        return today;
    }

    public void setToday(Date today) {
        this.today = today;
    }

    public String getCaseMatch() {
        return caseMatch;
    }

    public void setCaseMatch(String caseMatch) {
        this.caseMatch = caseMatch;
    }

    public int getSpinnerField() {
        return spinnerField;
    }

    public void setSpinnerField(int spinnerField) {
        this.spinnerField = spinnerField;
    }

    public Marking getMarkSectionOne() {
        return markSectionOne;
    }

    public void setMarkSectionOne(Marking markSectionOne) {
        this.markSectionOne = markSectionOne;
    }

    public Marking getStudentNumber() {
        return studentNumber;
    }

    public void setStudentNumber(Marking studentNumber) {
        this.studentNumber = studentNumber;
    }

    public MarkingService getMarkingService() {
        return markingService;
    }

    public void setMarkingService(MarkingService markingService) {
        this.markingService = markingService;
    }

    public MarkingFacade getMarkingFacade() {
        return markingFacade;
    }

    public void setMarkingFacade(MarkingFacade markingFacade) {
        this.markingFacade = markingFacade;
    }

}

but currently only adds a new row with the data to the database rather than trying to merge it with the data already contained in the database for a student with a certain student number

how can i achieve this ? thanks guys for your help :)

EDIT :

I have tried :

 private Marking markToEdit;

    @Inject
    private MarkingFacade markingFacade;

    @PostConstruct
    public void init() {
        this.markToEdit = this.markingFacade.find(studentNumber);
        //this.markSectionTwo = new Marking();
    }

    public String markSectionTwo() {
        this.markingFacade.edit(markSectionTwo);
        this.setMessage("Mark Saved");
       // markSectionTwo = new Marking();
        //this.setMessage("Mark Saved");
        // now navigating to the next page
        return "/lecturer/marking/marking-section-three";
    }

but get the error :

exception

javax.servlet.ServletException: WELD-000049 Unable to invoke public void sws.control.EditMarkingController.init() on sws.control.EditMarkingController@4109691f
root cause

org.jboss.weld.exceptions.WeldException: WELD-000049 Unable to invoke public void sws.control.EditMarkingController.init() on sws.control.EditMarkingController@4109691f
root cause

java.lang.reflect.InvocationTargetException
root cause

javax.ejb.EJBException
root cause

java.lang.IllegalArgumentException: An instance of a null PK has been incorrectly provided for this find operation.

Solution

  • I use a quite similar approach as yours, but with different names. I'll post it here, so I think you can have some idea.

    My way is to check the entity explicitly before merging it.

    My JSF CRUD looks like this

    xhtml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:p="http://primefaces.org/ui">
    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>DataSource Manager</title>
    </h:head>
    <h:body>
        <h:form id="ds">
    
            <p:spacer height="10" />
            <p:fieldset legend="Insert/Edit Data Source">
            <p:panel id="insertUpdateForm">
            <h:panelGrid columns="2">
    
                <p:outputLabel for="name" value="Data Source Name:" style="width:100px;"/>  
                <p:inputText id="name" value="#{dataSourceMB.dataSource.name}"/>
    
    
                <p:outputLabel for="user" value="User:" style="width:100px;"/>  
                <p:inputText id="user" value="#{dataSourceMB.dataSource.user}"/>
    
    
                <p:outputLabel for="driver" value="Driver:" style="width:100px;"/>  
                <p:inputText id="driver" value="#{dataSourceMB.dataSource.driver}" />
    
            </h:panelGrid>
            </p:panel>
    
            <p:panel>
                <p:commandButton value="Save" action="#{dataSourceMB.saveDataSource}" update="dsList,insertUpdateForm" />
                <p:commandButton value="Clear" action="#{dataSourceMB.clearDataSource}" update="insertUpdateForm" />
                <p:commandButton value="Test Connection" action="#{dataSourceMB.testConnection}"/>
            </p:panel>
    
            </p:fieldset>
    
    
            <p:spacer height="10" />
            <p:fieldset legend="Data Sources">    
            <p:panel>
                <p:dataTable 
                    var="ds" 
                    value="#{dataSourceMB.listDataSources}" 
                    paginator="true" rows="10"  
                    paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"  
                    rowsPerPageTemplate="10,50,100"
                    id="dsList">  
    
                <p:column headerText="ID">                
                    <h:outputText value="#{ds.id}" />  
                </p:column>
                <p:column headerText="Name">                  
                    <h:outputText value="#{ds.name}" />  
                </p:column>
                <p:column headerText="JDBC">                  
                    <h:outputText value="#{ds.jdbc} " />  
                </p:column>
    
                <!-- check http://jqueryui.com/themeroller/ for icons -->             
    
                <p:column headerText="" style="width:2%">  
                    <p:commandButton  icon="ui-icon-pencil" action="#{dataSourceMB.editDataSource}" title="Edit" update=":ds:insertUpdateForm">   
                        <f:setPropertyActionListener value="#{ds}" target="#{dataSourceMB.selectedDataSource}" />  
                    </p:commandButton>  
                </p:column>                           
                <p:column headerText="" style="width:2%">  
                    <p:commandButton  icon="ui-icon-trash" action="#{dataSourceMB.removeDataSource}" title="Remove" update=":ds:insertUpdateForm,dsList">  
                        <f:setPropertyActionListener value="#{ds}" target="#{dataSourceMB.selectedDataSource}" />  
                    </p:commandButton>              
                </p:column>  
                </p:dataTable>
            </p:panel>
            </p:fieldset>
        </h:form>
    </h:body>
    </html>
    

    my managed bean

    import java.io.Serializable;
    import java.util.List;
    
    import javax.annotation.PostConstruct;
    import javax.ejb.EJB;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;
    
    import org.apache.log4j.Logger;
    
    import DataSourceEJB;
    import JSFUtilEJB;
    import DataSource;
    
    @ManagedBean
    @ViewScoped
    public class DataSourceMB implements Serializable {
    
        private static final long serialVersionUID = 871363306742707990L;
        private static Logger log = Logger.getLogger(DataSourceMB.class);
    
        @EJB
        private JSFUtilEJB jsfUtilEJB;
    
        @EJB
        private DataSourceEJB dataSourceEJB;
    
        private DataSource dataSource;
        private DataSource selectedDataSource;
        private List<DataSource> listDataSources;
    
        @PostConstruct
        public void init() {
            try {
                this.dataSource = new DataSource();
                this.listDataSources = this.dataSourceEJB.listDataSources();
            } catch (Exception e) {
                jsfUtilEJB.addErrorMessage(e,"Could not list");
            }
        }
    
        public void removeDataSource(){
            try {
                this.dataSourceEJB.removeDataSource(this.selectedDataSource);
                jsfUtilEJB.addInfoMessage("Removed "+this.selectedDataSource.getName());
    
                if (this.dataSource != null && this.dataSource.getId() != null && this.dataSource.getId().equals(this.selectedDataSource.getId())){
                    this.dataSource = null;
                }
                this.listDataSources = this.dataSourceEJB.listDataSources();
    
            } catch (Exception e) {
                jsfUtilEJB.addErrorMessage(e,"Could not remove");
            }
        }
    
        public void saveDataSource(){
            try {
                this.dataSourceEJB.saveDataSource(this.dataSource);
                jsfUtilEJB.addInfoMessage("Saved "+this.dataSource.getName());
    
                this.dataSource = new DataSource();
                this.listDataSources = this.dataSourceEJB.listDataSources();
            } catch (Exception e) {
                jsfUtilEJB.addErrorMessage(e,"Could not save");
            }
        }
    
        public void editDataSource(){
            this.dataSource = this.selectedDataSource;
    
        }
    
        public void clearDataSource(){
            this.dataSource = new DataSource();
        }
    
        public DataSource getDataSource() {
            return dataSource;
        }
    
        public void setDataSource(DataSource dataSource) {
            this.dataSource = dataSource;
        }
    
        public DataSource getSelectedDataSource() {
            return selectedDataSource;
        }
    
        public void setSelectedDataSource(DataSource selectedDataSource) {
            this.selectedDataSource = selectedDataSource;
        }
    
        public List<DataSource> getListDataSources() {
            return listDataSources;
        }
    
        public void setListDataSources(List<DataSource> listDataSources) {
            this.listDataSources = listDataSources;
        }
    
    }
    

    my EJB

    import java.io.IOException;
    import java.sql.SQLException;
    import java.util.List;
    
    import javax.ejb.Stateless;
    import javax.inject.Inject;
    
    import DataSource;
    
    @Stateless
    public class DataSourceEJB {
    
        @Inject
        private BaseService baseService;
    
        public List<DataSource> listDataSources() {
            return this.baseService.getDataSourceDAO().getAll();
        }
    
    
        public void removeDataSource(DataSource ds) throws Exception {
            DataSource a = this.baseService.getDataSourceDAO().find(ds.getId()); 
            this.baseService.getDataSourceDAO().delete(a);      
        }
    
        public void saveDataSource(DataSource ds) throws Exception {
            DataSource a = this.baseService.getDataSourceDAO().find(ds.getId());
            if (a == null){
                this.baseService.getDataSourceDAO().add(ds);
            }else{
                this.baseService.getDataSourceDAO().edit(ds);
            }       
        }
    
        public DataSource getById(long id) {
            return this.baseService.getDataSourceDAO().find(id);
        }
    
        public DataSource getByName(String name) {
            return this.baseService.getDataSourceDAO().findByName(name);
        }
    
    }
    

    DAO

    public E find(Long id) {
        return (E)entityManager.find(clazz, id);
    }
    
    public void add(E entity) throws Exception {
        entityManager.persist(entity);
    }
    
    
    public E edit(E entity) throws Exception {
        return entityManager.merge(entity);
    }
    
    
    public void delete(E entity) throws Exception {
        entityManager.remove(entity);
    }