-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Why is Hibernate updating after a select?
PostPosted: Wed Feb 02, 2011 11:11 am 
Newbie

Joined: Tue Jan 18, 2011 10:02 am
Posts: 4
Hi everyone,

I have a wierd problem with my code. I'm using JPA/Hibernate, and for some odd reason (well odd to me at least), Hibernate is performing an update on very row in my table after doing a select. When I make a call to a method that simply does "from OwordDocuments" to return a List of OwordDocuments object, Hibernate befores an update on every row in my table. I noticed that when I switch one of the fields in my table from a TemporalType.TIMESTAMP to TemporalType.DATE, this update does not occur. Why is that?

Here is my class that was generated by Hibernate...

Code:
package ca.mcgill.muhc.oword;

// Generated 26-Jan-2011 7:23:01 PM by Hibernate Tools 3.3.0.GA

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.apache.log4j.Logger;

/**
* OwordDocuments generated by hbm2java
*/
@Entity
@Table(name = "OWORD_DOCUMENTS")
public class OwordDocuments implements java.io.Serializable {

   private static final long serialVersionUID = -8742054957594826092L;
   private int documentId;
   private OwordStatus owordStatus;
   private OwordTemplates owordTemplates;
   private int userId;
   private Date updateDate;
   private byte[] draftDocument;
   private byte[] finalDocument;
   private String mrn;
   private String site;
   private String visitNumber;
   private int patientId;
   private char sex;
   private String ramqNumber;
   private String firstName;
   private String middleName;
   private String lastName;
   private Date createDate;
   private String createdBy;
   private String updatedBy;
   private Date admitDate;
   private Date dischargeDate;

   private static Logger log = Logger.getLogger( OwordDocuments.class );

   public OwordDocuments() {
   }

   public OwordDocuments(int documentId, String mrn) {
      this.documentId = documentId;
      this.mrn = mrn;
   }

   public OwordDocuments(int documentId, OwordStatus owordStatus, OwordTemplates owordTemplates,
         int userId, Date updateDate, byte[] draftDocument, byte[] finalDocument, String mrn,
         String site, int patientId, char sex, String ramqNumber, String firstName, String lastName,
         Date createDate, String updatedBy) {
      this.documentId = documentId;
      this.owordStatus = owordStatus;
      this.owordTemplates = owordTemplates;
      this.userId = userId;
      this.updateDate = updateDate;
      this.draftDocument = draftDocument;
      this.finalDocument = finalDocument;
      this.mrn = mrn;
      this.site = site;
      this.patientId = patientId;
      this.sex = sex;
      this.ramqNumber = ramqNumber;
      this.firstName = firstName;
      this.lastName = lastName;
      this.createDate = createDate;
      this.updatedBy = updatedBy;
   }

   public OwordDocuments(int documentId, OwordStatus owordStatus,
         OwordTemplates owordTemplates, int userId, Date updateDate,
         byte[] draftDocument, byte[] finalDocument, String mrn,
         String site, String visitNumber, int patientId, char sex,
         String ramqNumber, String firstName, String middleName,
         String lastName, Date createDate, String updatedBy,
         Date admitDate, Date dischargeDate) {
      this.documentId = documentId;
      this.owordStatus = owordStatus;
      this.owordTemplates = owordTemplates;
      this.userId = userId;
      this.updateDate = updateDate;
      this.draftDocument = draftDocument;
      this.finalDocument = finalDocument;
      this.mrn = mrn;
      this.site = site;
      this.visitNumber = visitNumber;
      this.patientId = patientId;
      this.sex = sex;
      this.ramqNumber = ramqNumber;
      this.firstName = firstName;
      this.middleName = middleName;
      this.lastName = lastName;
      this.createDate = createDate;
      this.updatedBy = updatedBy;
      this.admitDate = admitDate;
      this.dischargeDate = dischargeDate;
   }

   @Id
   @Column(name = "DOCUMENT_ID", unique = true, nullable = false, precision = 38, scale = 0, updatable = false)
   @GeneratedValue(strategy = GenerationType.AUTO)
   public int getDocumentId() {
      return this.documentId;
   }

   public void setDocumentId(int documentId) {
      log.info("1");
      this.documentId = documentId;
   }

   @ManyToOne
   @JoinColumn(name = "STATUS_CODE")
   public OwordStatus getOwordStatus() {
      return this.owordStatus;
   }

   public void setOwordStatus(OwordStatus owordStatus) {
      log.info("2");
      this.owordStatus = owordStatus;
   }

   @ManyToOne
   @JoinColumn(name = "TEMPLATE_ID")
   public OwordTemplates getOwordTemplates() {
      return this.owordTemplates;
   }

   public void setOwordTemplates(OwordTemplates owordTemplates) {
      log.info("3");
      this.owordTemplates = owordTemplates;
   }

   @Column(name = "USER_ID", precision = 38, scale = 0)
   public int getUserId() {
      return this.userId;
   }

   public void setUserId(int userId) {
      log.info("4");
      this.userId = userId;
   }

   @Temporal(TemporalType.TIMESTAMP)
   @Column(name = "UPDATE_DATE")
   public Date getUpdateDate() {
      return this.updateDate;
   }

   public void setUpdateDate(Date updateDate) {
      log.info("5");
      this.updateDate = new Date();
   }

   @Lob
   @Column(name = "DRAFT_DOCUMENT")
   public byte[] getDraftDocument() {
      return this.draftDocument;
   }

   public void setDraftDocument(byte[] draftDocument) {
      log.info("6");
      this.draftDocument = draftDocument;
   }

   @Lob
   @Column(name = "FINAL_DOCUMENT")
   public byte[] getFinalDocument() {
      return this.finalDocument;
   }

   public void setFinalDocument(byte[] finalDocument) {
      log.info("7");
      this.finalDocument = finalDocument;
   }

   @Column(name = "MRN", length = 15)
   public String getMrn() {
      return this.mrn;
   }

   public void setMrn(String mrn) {
      log.info("8");
      this.mrn = mrn;
   }

   @Column(name = "SITE", length = 15)
   public String getSite() {
      return this.site;
   }

   public void setSite(String site) {
      log.info("9");
      this.site = site;
   }

   @Column(name = "VISIT_NUMBER", length = 15)
   public String getVisitNumber() {
      return this.visitNumber;
   }

   public void setVisitNumber(String visitNumber) {
      log.info("10");
      this.visitNumber = visitNumber;
   }

   @Column(name = "PATIENT_ID", precision = 38, scale = 0)
   public int getPatientId() {
      return this.patientId;
   }

   public void setPatientId(int patientId) {
      log.info("11");
      this.patientId = patientId;
   }

   @Column(name = "SEX", length = 1)
   public char getSex() {
      return this.sex;
   }

   public void setSex(char sex) {
      log.info("12");
      this.sex = sex;
   }

   @Column(name = "RAMQ_NUMBER", length = 15)
   public String getRamqNumber() {
      return this.ramqNumber;
   }

   public void setRamqNumber(String ramqNumber) {
      this.ramqNumber = ramqNumber;
   }

   @Column(name = "FIRST_NAME", length = 20)
   public String getFirstName() {
      return this.firstName;
   }

   public void setFirstName(String firstName) {
      this.firstName = firstName;
   }

   @Column(name = "MIDDLE_NAME", length = 20)
   public String getMiddleName() {
      return this.middleName;
   }

   public void setMiddleName(String middleName) {
      this.middleName = middleName;
   }

   @Column(name = "LAST_NAME", length = 40)
   public String getLastName() {
      return this.lastName;
   }

   public void setLastName(String lastName) {
      this.lastName = lastName;
   }

   @Temporal(TemporalType.TIMESTAMP)
   @Column(name = "CREATE_DATE", updatable = false)
   public Date getCreateDate() {
      return this.createDate;
   }

   public void setCreateDate(Date createDate) {
      this.createDate = new Date();
   }

   @Column(name = "CREATED_BY", length = 30)
   public String getCreatedBy() {
      return this.createdBy;
   }

   public void setCreatedBy(String createdBy) {
      this.createdBy = createdBy;
   }

   @Column(name = "UPDATED_BY", length = 30)
   public String getUpdatedBy() {
      return this.updatedBy;
   }

   public void setUpdatedBy(String updatedBy) {
      this.updatedBy = updatedBy;
   }

   @Temporal(TemporalType.TIMESTAMP)
   @Column(name = "ADMIT_DATE")
   public Date getAdmitDate() {
      return this.admitDate;
   }

   public void setAdmitDate(Date admitDate) {
      this.admitDate = admitDate;
   }

   @Temporal(TemporalType.TIMESTAMP)
   @Column(name = "DISCHARGE_DATE")
   public Date getDischargeDate() {
      return this.dischargeDate;
   }

   public void setDischargeDate(Date dischargeDate) {
      this.dischargeDate = dischargeDate;
   }

}


As I said, when I switch the field updateDate on line 158 to @Temporal(TemporalType.DATE), this update does not happen.

Here is my class that executes the select...

Code:
package ca.mcgill.muhc.oword;

import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;

@Stateless
public class OwordDocumentsQueryBean implements OwordDocumentsQuery {

   @PersistenceContext( unitName = "oword" )
   EntityManager oword;

   private static Logger log = Logger.getLogger( OwordDocumentsQueryBean.class );

   private static final String GET_ALL_DOCUMENTS = "from OwordDocuments";

   @SuppressWarnings( "unchecked" )
   public List<OwordDocuments> getAllDocuments() {
      log.info("Start of OwordDocumentsQueryBean.getAllDocuments()");

      Query qry = oword.createQuery(GET_ALL_DOCUMENTS);

      return qry.getResultList();
   }

}


Any ideas why the updates are happening, and how I can stop it from happening?


Top
 Profile  
 
 Post subject: Re: Why is Hibernate updating after a select?
PostPosted: Wed Feb 02, 2011 12:53 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Code:
public void setUpdateDate(Date updateDate) {
      log.info("5");
      this.updateDate = new Date();
   }


This is most likely the source of your problem. Since you are ignoring the old value and setting it to the current date+time Hibernate will detect a change in your object and thus issue an update statement when flushing the session. The reason that it doesn't happen when you change it to a DATE is probably that it is more likely that the old and new value are on the same date. I guess the update will happen in this case also given that the old value is an earlier date.

To solve this the first step is to change your setter so that it stores the old value and doesn't create a new Date all the time. I guess that you want the value to automatically get updated when there is a "real" change to your object. That can be done in different ways, for example, using an Interceptor (http://docs.jboss.org/hibernate/core/3. ... vents.html), or by using that column as a "version" column (http://docs.jboss.org/hibernate/core/3. ... ml#d0e5785).


Top
 Profile  
 
 Post subject: Re: Why is Hibernate updating after a select?
PostPosted: Wed Feb 02, 2011 9:17 pm 
Newbie

Joined: Tue Jan 18, 2011 10:02 am
Posts: 4
Thanks for the reply. Your theory is correct, by removing...

Code:
this.updateDate = new Date();


and replacing it with...
Code:
this.updateDate = updateDate;


the updates are no longer occurring. I had a look at the links you provided, but I'm afraid I'm not sure how I can use either of those solutions in my application (keep in mind I'm very new to Hibernate, this in fact is my first time working with Hibernate). For example in the case of using an Interceptor, I'm not sure how it would work in my web service given that to the best of my limited Hibernate knowledge, I'm not using sessions. Would you happen to know of an example that uses Interceptor that my be helpful to me? What about using something like either @PreUpdate or @PostUpdate? I tried using the @Version solution, but I'm must have done something wrong because I was still get updates after select.


Top
 Profile  
 
 Post subject: Re: Why is Hibernate updating after a select?
PostPosted: Thu Feb 03, 2011 3:11 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Quote:
I'm not sure how it would work in my web service given that to the best of my limited Hibernate knowledge, I'm not using sessions.


So what are you using?


Top
 Profile  
 
 Post subject: Re: Why is Hibernate updating after a select?
PostPosted: Thu Feb 03, 2011 3:05 pm 
Newbie

Joined: Tue Jan 18, 2011 10:02 am
Posts: 4
nordborg wrote:
So what are you using?


That's a good question, to which I have no answer. What I know is that I'm not creating a session anywhere in my code.

In any case I found what appears to be a solution to my problem. I added the following in the Hibernate class...

Code:
@PrePersist
@PreUpdate
public void updateUpdateDate() {
   this.updateDate = new Date();
}


I'm not sure if this is the right/best solution, but now I no longer having updates after a select, and at the same time, my date field is being updated every time the row is being updated.

Thank you for your help in finding out where exactly the source of the problem was.


Top
 Profile  
 
 Post subject: Re: Why is Hibernate updating after a select?
PostPosted: Thu Feb 03, 2011 6:12 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
It's great to hear that you solved the problem. I have no experience myself with @PrePersist/@PreUpdate annotations. Seems like a nice feaure!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.