10 Replies Latest reply on Mar 18, 2010 1:42 PM by Ilya Dyoshin

    EntityHome NOT updating database record

    Charlie B Newbie

      Hi,


      I am having problems with EntityHome component. I have a action bean which loops through a list of entities and updates each one in the database.


      The return messgae is Updated and everything goes smooth. However, when i look in the DB, the new values are not there.


      Im not sure what im doing wrong.


      The managed entity does contain an @EmbeddedId...but im not sure if this will cause any problems when updating the records. I print out each one of the entities embeddedId attributes, and they are all there and correct...there shouldn't be a problem locating the entity.


      Here is the action bean:



      package au.com.statewater.koncentrator.action;
      
      import java.io.Serializable;
      import java.util.Iterator;
      import java.util.List;
      import java.util.Map;
      
      import javax.el.ValueExpression;
      import javax.faces.event.ValueChangeEvent;
      
      import org.jboss.seam.ScopeType;
      import org.jboss.seam.annotations.In;
      import org.jboss.seam.annotations.Logger;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.Out;
      import org.jboss.seam.annotations.datamodel.DataModel;
      import org.jboss.seam.log.Log;
      
      import sun.security.krb5.internal.rcache.AuthTime;
      
      import au.com.statewater.koncentrator.action.home.ReadingHome;
      import au.com.statewater.koncentrator.action.list.ReadingList;
      import au.com.statewater.koncentrator.entity.Reading;
      import au.com.statewater.koncentrator.entity.Site;
      import au.com.statewater.koncentrator.entity.Variable;
      
      @Name("inputDataAction")
      public class InputDataAction implements Serializable {
           
           /**
            * Auto-Generated serialVersion ID
            */
           private static final long serialVersionUID = -1655547309652687382L;
           
           @Logger Log log;
           
           @In(value = "readingHome", create = true)
           private ReadingHome readingQueryHome;
           
           @In("#{treeListener.readings}")
           List<Reading> readings;
           
           /**
            * Updates the users existing readings with the new values.
            */
           public void updateReadings() {
                
                log.info("QUery home: " + readingQueryHome);
                
                log.info("Updating list of readings.");
                log.info("Readings: " + readings);
                
                log.info("List of readings: " + readings.size());
                
                Iterator i = readings.iterator();
                Reading r;
                while (i.hasNext()) {
                     r = (Reading) i.next();
                     
                     
                     readingQueryHome.setInstance(r);
                     
                     log.info("Reading: " + readingQueryHome.getInstance().getId().getSiteId());
                     log.info("Reading: " + readingQueryHome.getInstance().getId().getVariableId());
                     log.info("Reading: " + readingQueryHome.getInstance().getId().getDate());
                     log.info("Reading: " + readingQueryHome.getInstance().getId().getTime());
                     log.info("Reading: " + readingQueryHome.getInstance().getValue());
                     log.info("====");
                     
                     String ret = readingQueryHome.update();
                                                   
                     log.info("DONE!!= " + ret);
                     
                }
           }
      
      }



      Is anyone able to help me point out what Im missing?


      Thanks in advance.


      Charlie


        • 1. Re: EntityHome NOT updating database record
          Charlie B Newbie

          After a few more tests, i've realised that even if I change the EmbeddedID to something that is not in the table, it still successfully completes and returns the Updated message...even though that record, based on the primary keys, does not exist.


          Here are my entity classes:




          package au.com.statewater.koncentrator.entity;
          // Generated 20/11/2009 10:56:16 AM by Hibernate Tools 3.2.4.GA
          
          import java.text.ParseException;
          import java.text.SimpleDateFormat;
          import java.util.Date;
          
          import javax.persistence.AttributeOverride;
          import javax.persistence.AttributeOverrides;
          import javax.persistence.Column;
          import javax.persistence.EmbeddedId;
          import javax.persistence.Entity;
          import javax.persistence.FetchType;
          import javax.persistence.JoinColumn;
          import javax.persistence.ManyToOne;
          import javax.persistence.Table;
          import javax.persistence.Transient;
          
          import org.hibernate.validator.Length;
          import org.hibernate.validator.NotNull;
          
          /**
           * Reading generated by hbm2java
           */
          @Entity
          @Table(name = "MANOPSREAD")
          public class Reading implements java.io.Serializable {
          
               /**
                * Auto-Generated
                */
               private static final long serialVersionUID = 7335804846297650405L;
               private ReadingId      id;
               private Site           site;
               private Variable      variable;
               private String           value;
          
               public Reading() {
               }
          
               public Reading(ReadingId id, Site site, Variable variable) {
                    this.id = id;
                    this.site = site;
                    this.variable = variable;
               }
               public Reading(ReadingId id, Site site, Variable variable, String value) {
                    this.id = id;
                    this.site = site;
                    this.variable = variable;
                    this.value = value;
               }
          
               @EmbeddedId
               @AttributeOverrides({
                         @AttributeOverride(name = "time", column = @Column(name = "VTIME", nullable = false, length = 20)),
                         @AttributeOverride(name = "date", column = @Column(name = "VDATE", nullable = false, length = 20)),
                         @AttributeOverride(name = "variableId", column = @Column(name = "VARID", nullable = false, length = 10)),
                         @AttributeOverride(name = "siteId", column = @Column(name = "SITEID", nullable = false, length = 10))})
               @NotNull
               public ReadingId getId() {
                    return this.id;
               }
          
               public void setId(ReadingId id) {
                    this.id = id;
               }
          
               @ManyToOne(fetch = FetchType.LAZY)
               @JoinColumn(name = "SITEID", nullable = false, insertable = false, updatable = false)
               @NotNull
               public Site getSite() {
                    return this.site;
               }
          
               public void setSite(Site site) {
                    this.site = site;
               }
          
               @ManyToOne(fetch = FetchType.LAZY)
               @JoinColumn(name = "VARID", nullable = false, insertable = false, updatable = false)
               @NotNull
               public Variable getVariable() {
                    return this.variable;
               }
          
               public void setVariable(Variable variable) {
                    this.variable = variable;
               }
          
               @Column(name = "SVALUE", length = 10)
               @Length(max = 10)
               public String getValue() {
                    return this.value;
               }
          
               public void setValue(String value) {
                    this.value = value;
               }
               
               @Transient
               public Date getDate() {
                    
                    SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
                    
                    try {
                         return df.parse(getId().getDate() + getId().getTime());
                    } catch (ParseException e) {
                         System.out.println("Parse Exception Caught while getting Variable Date: " + e.toString());
                         return null;
                    } 
               }
          
          }






          package au.com.statewater.koncentrator.entity;
          // Generated 20/11/2009 10:56:16 AM by Hibernate Tools 3.2.4.GA
          
          import javax.persistence.Column;
          import javax.persistence.Embeddable;
          import org.hibernate.validator.Length;
          import org.hibernate.validator.NotNull;
          
          /**
           * ReadingId generated by hbm2java
           */
          @Embeddable
          public class ReadingId implements java.io.Serializable {
          
               /**
                * Auto-Generated
                */
               private static final long serialVersionUID = -4580171058168490886L;
               private String time;
               private String date;
               private String variableId;
               private String siteId;
          
               public ReadingId() {
               }
          
               public ReadingId(String variableId, String siteId) {
                    this.variableId = variableId;
                    this.siteId = siteId;
               }
               
               public ReadingId(String time, String date, String variableId, String siteId) {
                    this.time = time;
                    this.date = date;
                    this.variableId = variableId;
                    this.siteId = siteId;
               }
          
               @Column(name = "VTIME", nullable = false, length = 20)
               @NotNull
               @Length(max = 20)
               public String getTime() {
                    return this.time;
               }
          
               public void setTime(String time) {
                    this.time = time;
               }
          
               @Column(name = "VDATE", nullable = false, length = 20)
               @NotNull
               @Length(max = 20)
               public String getDate() {
                    return this.date;
               }
          
               public void setDate(String date) {
                    this.date = date;
               }
          
               @Column(name = "VARID", nullable = false, length = 10)
               @NotNull
               @Length(max = 10)
               public String getVariableId() {
                    return this.variableId;
               }
          
               public void setVariableId(String variableId) {
                    this.variableId = variableId;
               }
          
               @Column(name = "SITEID", nullable = false, length = 10)
               @NotNull
               @Length(max = 10)
               public String getSiteId() {
                    return this.siteId;
               }
          
               public void setSiteId(String siteId) {
                    this.siteId = siteId;
               }
          
               public boolean equals(Object other) {
                    if ((this == other))
                         return true;
                    if ((other == null))
                         return false;
                    if (!(other instanceof ReadingId))
                         return false;
                    ReadingId castOther = (ReadingId) other;
          
                    return ((this.getTime() == castOther.getTime()) || (this.getTime() != null
                              && castOther.getTime() != null && this.getTime().equals(
                              castOther.getTime())))
                              && ((this.getDate() == castOther.getDate()) || (this.getDate() != null
                                        && castOther.getDate() != null && this.getDate()
                                        .equals(castOther.getDate())))
                              && ((this.getVariableId() == castOther.getVariableId()) || (this
                                        .getVariableId() != null
                                        && castOther.getVariableId() != null && this
                                        .getVariableId().equals(castOther.getVariableId())))
                              && ((this.getSiteId() == castOther.getSiteId()) || (this
                                        .getSiteId() != null
                                        && castOther.getSiteId() != null && this.getSiteId()
                                        .equals(castOther.getSiteId())));
               }
          
               public int hashCode() {
                    int result = 17;
          
                    result = 37 * result
                              + (getTime() == null ? 0 : this.getTime().hashCode());
                    result = 37 * result
                              + (getDate() == null ? 0 : this.getDate().hashCode());
                    result = 37
                              * result
                              + (getVariableId() == null ? 0 : this.getVariableId()
                                        .hashCode());
                    result = 37 * result
                              + (getSiteId() == null ? 0 : this.getSiteId().hashCode());
                    return result;
               }
          
          }



          Any help would be much appreciated.
          Charlie


          • 2. Re: EntityHome NOT updating database record
            Ilya Dyoshin Novice

            I think it could be with transactions. And according to your code try something similar to:


            @In
            EntityManager entityManager;
            
            
            @Transactional
            public void updateReadings() {
            
                ....
              
                entityManager.flush();
            }



            • 3. Re: EntityHome NOT updating database record
              Charlie B Newbie

              Thanks for your reply.


              After heaps of debugging, i've come to realise that the reason the value is not updating, is because the entityHome instance that is being updated, contains the original value from the database when the update() method is called.


              Not sure why this is.


              I call entityHome.setInstance(entityInstance) and then call entityHome.update().


              This seems straight forward and should work...but for some reason, the code seems to be retrieving the original record from the database table before calling update, and therefore, my new value is lost and not saved.


              Can you offer any insight on how to use the entityHome.update() method correctly?
              It seems that setInstance method doesn't do what its suppose to do. Do I need to set the Id on the entityHome as well?


              Any help would be appreciated.


              Charlie


              • 4. Re: EntityHome NOT updating database record
                Ilya Dyoshin Novice

                If your entities are attached to entityManager you can simply call entityManager.flush() for sending changes to database. If you still need to use EntityHome I would suggest following solution:


                // loads entity to the entityHome from database;
                EntityHome.setId(instance.id);
                
                // Set entityHome managed instance's properties
                EntityHome.getInstance().setProperty(instance.getProperty());
                ...
                
                // and update entities:
                EntityHome.update();
                
                
                // if you would like to create new one. 
                EntityHome.setId(null);
                EntityHome.clearInstance();
                
                EntityHome.getInstance().setId(yourCompositeID);
                
                EntityHome.getInstance().setProperty(property);
                
                // and in the end;
                EntityHome.save();



                The whole bunch should be called with @Transactional method.

                • 5. Re: EntityHome NOT updating database record
                  Charlie B Newbie

                  Thanks for your help.


                  Was able to get it working.

                  • 6. Re: EntityHome NOT updating database record
                    Charlie B Newbie

                    Sorry to come back to this.


                    But although it worked and updated my values...I had another problem with it.


                    If I update a value the first time, then its all good.
                    But if I try to update the value again, with another value, once the page reloads, I get NullPointerException.


                    I do exactly what you mentioned, but the EntityHome.getInstance() method, the second time around, returns a NULL instance.


                    Would you know why this would be?


                    Thanks in advance.


                    Charlie

                    • 7. Re: EntityHome NOT updating database record
                      Ilya Dyoshin Novice

                      You should verify the EntityHome' Scope. I've been in similar trouble while I've been using PAGE scope. It's always better to use CONVERSATION Scope. This is the only one problem I can guess.


                      In general, I need some more information to be more precise. I.e. how you change the code, and have you overrided the createInstance() method of EntityHome?


                      Regards,
                      Ilya Dyoshin

                      • 8. Re: EntityHome NOT updating database record
                        Charlie B Newbie

                        Thanks for your help.


                        It was a scope issue. Once I corrected that, it all worked perfectly.


                        Thanks again.


                        Charlie

                        • 9. Re: EntityHome NOT updating database record
                          Alex Lam Newbie

                          Another thing that worked for me was using  h:commandButton instead of s:Button and of course both the button and the input within a form.

                          • 10. Re: EntityHome NOT updating database record
                            Ilya Dyoshin Novice

                            Alex Lam wrote on Mar 18, 2010 13:35:


                            Another thing that worked for me was using  h:commandButton instead of s:Button and of course both the button and the input within a form.


                            Well that's obvious.  s:Button is actually a LINK  - NOT BUTTON.



                            Kind regards,


                            Ilya Dyoshin