Ok, here's the problem: I am trying to set up automatic versioning for a Last Updated calendar field. I created the version tag immediately following the ID tag and specified the type as calendar. I then tried saving a new bean w/out explicitly setting the last updated field, since the documentation specifies that hibernate manages that field for me. Alas, the stack trace below was the result. I then changed the code so that on save of a new class, I would eplicitly set the last updated field. This fixed the error on save. However, I have the same problem now on update whether I explicitly set the field or simply retain the original value (which should be the correct approach for version checking).
I have two questions:
1) Why is the value not automatically set on save as the documentation seems to indicate it is?
2) Why does the update give me this error whether I explicitly set the 'version' field or not?
Oh, one other thing: I have tried timestamp, but that is incompatible with our Calendar field.
Thanks for your help!
Hibernate version: 2.1
Name and version of the database you are using: Oracle 9i
Java Version 1.5.0_01
Mapping documents:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.sas.edu.educentral.edusa.beans.DiscountProgram" table="DISC_PGM" optimistic-lock="version">
<!-- ID generated by custom class (String). -->
<id name="ID" type="java.lang.String" column="DISC_PGM_ID" unsaved-value="null" >
<generator class="com.sas.edu.educentral.system.EduCentralIdentifierGenerator"/>
</id>
<version type="calendar" name="lastUpdated" column="LASTUPDATED"/>
<property name="code">
<column name="DISC_PGM_CODE" length="20" not-null="true"/>
</property>
<property name="name">
<column name="DISC_PGM_NAME" length="100" not-null="true"/>
</property>
<property name="type">
<column name="DISC_PGM_TYPE" length="1" not-null="true"/>
</property>
<property name="oneOffer">
<column name="ONE_OFFER" length="1" not-null="true"/>
</property>
<property name="adminLevel">
<column name="ADMIN_LEVEL" length="1" not-null="true"/>
</property>
<property name="publicOnsite">
<column name="PUBLIC_ONSITE" length="1" not-null="true"/>
</property>
<property name="invoiceCredit">
<column name="INV_CRED" length="1" not-null="true"/>
</property>
<property name="startDate">
<column name="START_DATE" not-null="true"/>
</property>
<property name="endDate">
<column name="END_DATE" not-null="false"/>
</property>
<property name="created">
<column name="CREATED" not-null="true"/>
</property>
<property name="createdBy">
<column name="CREATEDBY" length="20" not-null="true"/>
</property>
<property name="lastUpdatedBy">
<column name="LASTUPDATEDBY" length="20" not-null="true"/>
</property>
</class>
</hibernate-mapping>
Bean
package com.sas.edu.educentral.edusa.beans;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import com.sas.edu.educentral.main.employee.domain.SASEmployeeAction;
import com.sas.edu.educentral.system.utils.formats.DateFormats;
/**
* Represents a Education Discount Program, such as EPTO.
* @author ryalbe
* Created on: 2/17/2005
*/
public class DiscountProgram {
private String ID = null; // primary ID for the discount program.
private String code = null; // display code for this program (ex. EPTO)
private String name = null; // the full name for this program (ex. Education Prepaid Training Offer)
private String type = null; // flag: unit-based (U) or course-based (C)
private String oneOffer = null; // flag: one-time offer per account/user -- yes (Y), no (N)
private String adminLevel = null; // flag: group (G) or individual (I) usage
private String publicOnsite = null; // flag: offer valid for both (B), public only (P), onsite-only (O)
private String invoiceCredit = null; // flag: paid for and invoiced (I), or credited/free (C)
private Calendar startDate = null; // date on which this program is available
private Calendar endDate = null; // date on which this program is no longer available
private String createdBy = null; // userID of the individual who created this record
private Calendar created = null; // date/time on which this record was created
private String lastUpdatedBy = null; // userID of the individual who last modified this record
private Calendar lastUpdated = null; // date/time on which this record was last updated
private List errorList = null; // list of errors in the bean fields
/**
* Empty constructor for discount program.
* @author ryalbe
*/
public DiscountProgram () {}
/**
* Sets the value of the ID attribute.
* @author ryalbe
* @param ID - string that is the unique identifier for this class
*/
public void setID( String ID ) {
if( ID != null && !ID.trim().equals("") ) {
this.ID = ID;
}
}
/**
* Retrieves the value of the ID attribute.
* @author ryalbe
* @return the String value of the ID attribute.
*/
public String getID() {
return this.ID;
}
/**
* Sets the value of the code attribute.
* @param code - the code for the discount program (ex. 'EPTO')
*/
public void setCode( String code ) {
this.code = code;
}
/**
* Retrieves the value of the code attribute.
* @author ryalbe
* @return the String value of the code attribute.
*/
public String getCode() {
return this.code;
}
/**
* Validates the code field and generates an error message if validation fails.
* @author ryalbe
* @return - message list if there is an error, null otherwise
*/
private void validateCode() {
if( this.code == null || this.code.trim().length() == 0 ) {
errorList.add( "No Program Code entered--code cannot be empty." );
}
else if( this.code.length() > 20 ) {
errorList.add( "Length of Program Code cannot exceed 20 characters." );
}
}
/**
* Sets the value of the name attribute.
* @param name - the name for the discount program
*/
public void setName( String name ) {
this.name = name;
}
/**
* Retrieves the value of the name attribute.
* @author ryalbe
* @return the String value of the name attribute.
*/
public String getName() {
return this.name;
}
/**
* Validates the name field and generates an error message if validation fails.
* @author ryalbe
* @return - message list if there is an error, null otherwise
*/
public void validateName() {
if( this.name == null || this.name.trim().length() == 0 ) {
errorList.add( "No Program Name entered--name cannot be empty." );
}
else if( this.name.length() > 100 ) {
errorList.add( "Length of Program Name cannot exceed 100 characters." );
}
}
/**
* Sets the value of the type attribute. This field remains null if an empty
* string is specified as a parameter to this method.
* @param type - the type for the discount program (unit or credit based)
*/
public void setType( String type ) {
if( type != null && type.trim().length() > 0 ) { this.type = type; }
}
/**
* Retrieves the value of the type attribute.
* @author ryalbe
* @return the String value of the type attribute.
*/
public String getType() {
return this.type;
}
/**
* Validates the type field and generates an error message if validation fails.
* @author ryalbe
* @return - message list if there is an error, null otherwise
*/
private void validateType() {
if( this.type == null || this.type.trim().length() == 0 ) {
errorList.add( "No Program Type specified--type must be selected." );
}
else if( this.type.length() > 1 ) {
errorList.add( "Length of Program Type cannot exceed 1 character." );
}
}
/**
* Sets the value of the oneOffer attribute. This field remains null if an empty
* string is specified as a parameter to this method.
* @param oneOffer - the oneOffer flag for the discount program (indicates whether or not this is a one-time use offer)
*/
public void setOneOffer( String oneOffer ) {
if( oneOffer != null && oneOffer.trim().length() > 0 ) { this.oneOffer = oneOffer; }
}
/**
* Retrieves the value of the oneOffer attribute.
* @author ryalbe
* @return the String value of the oneOffer attribute.
*/
public String getOneOffer() {
return this.oneOffer;
}
/**
* Validates the oneOffer field and generates an error message if validation fails.
* @author ryalbe
* @return - message list if there is an error, null otherwise
*/
private void validateOneOffer() {
if( this.oneOffer == null || this.oneOffer.trim().length() == 0 ) {
errorList.add( "One-Time Offer flag not set--One-Time Offer flag must be set." );
}
else if( this.oneOffer.length() > 1 ) {
errorList.add( "Length of One-Time Offer flag cannot exceed 1 character." );
}
}
/**
* Sets the value of the adminLevel attribute. This field remains null if an empty
* string is specified as a parameter to this method.
* @param adminLevel - the adminLevel setting for the discount program (individual usage or group usage)
*/
public void setAdminLevel( String adminLevel ) {
if( adminLevel != null && adminLevel.trim().length() > 0 ) { this.adminLevel = adminLevel; }
}
/**
* Retrieves the value of the adminLevel attribute.
* @author ryalbe
* @return the String value of the adminLevel attribute.
*/
public String getAdminLevel() {
return this.adminLevel;
}
/**
* Validates the adminLevel field and generates an error message if validation fails.
* @author ryalbe
* @return - message list if there is an error, null otherwise
*/
private void validateAdminLevel() {
if( this.adminLevel == null || this.adminLevel.trim().length() == 0 ) {
errorList.add( "Administration Level flag not set--Administration Level flag must be set." );
}
else if( this.adminLevel.length() > 1 ) {
errorList.add( "Length of Administration Level flag cannot exceed 1 character." );
}
}
/**
* Sets the value of the publicOnsite attribute. This field remains null if an empty
* string is specified as a parameter to this method.
* @param publicOnsite - the publicOnsite flag for the discount program (Public, Onsite, or usage for both is valid)
*/
public void setPublicOnsite( String publicOnsite ) {
if( publicOnsite != null && publicOnsite.trim().length() > 0 ) { this.publicOnsite = publicOnsite; }
}
/**
* Retrieves the value of the publicOnsite attribute.
* @author ryalbe
* @return the String value of the publicOnsite attribute.
*/
public String getPublicOnsite() {
return this.publicOnsite;
}
/**
* Validates the publicOnsite field and generates an error message if validation fails.
* @author ryalbe
* @return - message list if there is an error, null otherwise
*/
private void validatePublicOnsite() {
if( this.publicOnsite == null || this.publicOnsite.trim().length() == 0 ) {
errorList.add( "Public/Onsite field not set--Public/Onsite field must have a selection." );
}
else if( this.publicOnsite.length() > 1 ) {
errorList.add( "Length of Public/Onsite field cannot exceed 1 character." );
}
}
/**
* Sets the value of the invoiceCredit attribute. This field remains null if an empty
* string is specified as a parameter to this method.
* @param invoiceCredit - the invoiceCredit flag for the discount program (invoice = paid offer, credit = giveaway offer)
*/
public void setInvoiceCredit( String invoiceCredit ) {
if( invoiceCredit != null && invoiceCredit.trim().length() > 0 ) { this.invoiceCredit = invoiceCredit; }
}
/**
* Retrieves the value of the invoiceCredit attribute.
* @author ryalbe
* @return the String value of the invoiceCredit attribute.
*/
public String getInvoiceCredit() {
return this.invoiceCredit;
}
/**
* Validates the invoiceCredit field and generates an error message if validation fails.
* @author ryalbe
* @return - message list if there is an error, null otherwise
*/
private void validateInvoiceCredit() {
if( this.invoiceCredit == null || this.invoiceCredit.trim().length() == 0 ) {
errorList.add( "Invoice/Credit field not set--Invoice/Credit field must have a selection." );
}
else if( this.invoiceCredit.length() > 1 ) {
errorList.add( "Length of Invoice/Credit field cannot exceed 1 character." );
}
}
/**
* Sets the value of the startDate attribute. This method is used when setting the start
* date from a value read out of a JDBC resultset.
* @param startDate - the startDate for the discount program
*/
public void setStartDate( Date startDate ) {
if( startDate != null ) {
this.startDate = Calendar.getInstance(); // create the new calendar object
this.startDate.setTime( startDate ); // convert the date to the calendar object
this.startDate.set(Calendar.HOUR_OF_DAY, 23);
this.startDate.set(Calendar.MINUTE, 59);
this.startDate.set(Calendar.SECOND, 59);
this.startDate.set(Calendar.MILLISECOND, 999);
}
}
/**
* Sets the value of the startDate attribute.
* @param startDate - the startDate for the discount program
*/
public void setStartDate( Calendar startDate ) {
this.startDate = startDate;
if( this.startDate != null ) {
this.startDate.set(Calendar.HOUR_OF_DAY, 23);
this.startDate.set(Calendar.MINUTE, 59);
this.startDate.set(Calendar.SECOND, 59);
this.startDate.set(Calendar.MILLISECOND, 999);
}
}
/**
* Retrieves the value of the startDate attribute.
* @author ryalbe
* @return the String value of the startDate attribute.
*/
public Calendar getStartDate() {
return this.startDate;
}
/**
* Validates the startDate field and generates an error message if validation fails.
* @author ryalbe
* @return - message list if there is an error, null otherwise
*/
private void validateStartDate() {
if( this.startDate == null ) {
errorList.add( "Invalid start date--none specified." );
}
else if( this.ID == null && this.startDate.before(Calendar.getInstance()) ) {
errorList.add( "Invalid start date--the start date cannot be in the past." );
}
else if( this.endDate != null ) {
if( this.endDate.before(this.startDate) ) {
errorList.add( "Invalid start date--the start date cannot be after the end date." );
}
}
}
/**
* Sets the value of the endDate attribute. This method is used when setting the start
* date from a value read out of a JDBC resultset.
* @param endDate - the endDate for the discount program
*/
public void setEndDate(Date endDate) {
if( endDate != null ) {
this.endDate = Calendar.getInstance(); // create the new calendar object
this.endDate.setTime( endDate ); // convert the date to the calendar object
this.endDate.set(Calendar.HOUR_OF_DAY, 23);
this.endDate.set(Calendar.MINUTE, 59);
this.endDate.set(Calendar.SECOND, 59);
this.endDate.set(Calendar.MILLISECOND, 999);
}
}
/**
* Sets the value of the endDate attribute.
* @param endDate - the endDate for the discount program
*/
public void setEndDate( Calendar endDate ) {
this.endDate = endDate;
if( this.endDate != null ) {
this.endDate.set(Calendar.HOUR_OF_DAY, 23);
this.endDate.set(Calendar.MINUTE, 59);
this.endDate.set(Calendar.SECOND, 59);
this.endDate.set(Calendar.MILLISECOND, 999);
}
}
/**
* Retrieves the value of the endDate attribute.
* @author ryalbe
* @return the String value of the endDate attribute.
*/
public Calendar getEndDate() {
return this.endDate;
}
/**
* Validates the endDate field and generates an error message if validation fails.
* @author ryalbe
* @return - message list if there is an error, null otherwise
*/
private void validateEndDate() {
if( this.endDate != null ) {
if( this.ID == null && this.endDate.before(Calendar.getInstance()) ) {
errorList.add( "Invalid end date--the end date cannot be in the past." );
}
else if( this.startDate != null ) {
if( this.endDate.before(this.startDate) ) {
errorList.add( "Invalid end date--the end date cannot be before the start date." );
}
}
}
}
/**
* Sets the value of the Created attribute. This method is used when setting the start
* date from a value read out of a JDBC resultset.
* @author ryalbe
* @param created - date on which this record was created
*/
public void setCreated( Date created ) {
if( created != null ) {
this.created = Calendar.getInstance(); // create the new calendar object
this.created.setTime( created ); // convert the date to the calendar object
}
}
/**
* Sets the value of the created attribute.
* @author ryalbe
* @param startDate - the startDate for the discount program
*/
public void setCreated( Calendar created ) {
this.created = created;
}
/**
* Retrieves the value of the created attribute.
* @author ryalbe
* @return the calendar value of the created attribute.
*/
public Calendar getCreated() {
return this.created;
}
/**
* Sets the value of the createdBy attribute.
* @author ryalbe
* @param createdBy - user ID of the employee who created this record
*/
public void setCreatedBy( String createdBy ) {
this.createdBy = createdBy;
}
/**
* Retrieves the value of the createdBy attribute.
* @author ryalbe
* @return the String value of the createdBy attribute (user ID).
*/
public String getCreatedBy() {
return this.createdBy;
}
/**
* Retrieves the name of the employee who created this record.
* @author ryalbe
* @return the name (String) of the employee who created this record.
*/
public String getCreatedByName() {
SASEmployeeAction empAction = new SASEmployeeAction();
return empAction.getNameFromUserID( getCreatedBy() );
}
/**
* Sets the value of the lastUpdated attribute. This method is used when setting the start
* date from a value read out of a JDBC resultset.
* @author ryalbe
* @param lastUpdated - date on which this record was last updated
*/
public void setLastUpdated( Date lastUpdatedDate ) {
if( lastUpdatedDate != null ) {
this.lastUpdated = Calendar.getInstance(); // create the new calendar object
this.lastUpdated.setTime( lastUpdatedDate ); // convert the date to the calendar object
}
}
/**
* Sets the value of the lastUpdated attribute.
* @author ryalbe
* @param startDate - the startDate for the discount program
*/
public void setLastUpdated( Calendar lastUpdated ) {
this.lastUpdated = lastUpdated;
}
/**
* Retrieves the value of the lastUpdated attribute.
* @author ryalbe
* @return the calendar value of the lastUpdated attribute.
*/
public Calendar getLastUpdated() {
return this.lastUpdated;
}
/**
* Sets the value of the lastUpdatedBy attribute.
* @author ryalbe
* @param lastUpdatedBy - user ID of the employee who last updated this record
*/
public void setLastUpdatedBy( String lastUpdatedByID ) {
this.lastUpdatedBy = lastUpdatedByID;
}
/**
* Retrieves the value of the lastUpdatedBy attribute.
* @author ryalbe
* @return the String value of the lastUpdatedBy attribute (user ID).
*/
public String getLastUpdatedBy() {
return this.lastUpdatedBy;
}
/**
* Retrieves the name of the employee who lastUpdated this record.
* @author ryalbe
* @return the name (String) of the employee who last updated this record.
*/
public String getLastUpdatedByName() {
SASEmployeeAction empAction = new SASEmployeeAction();
return empAction.getNameFromUserID( getLastUpdatedBy() );
}
/**
* Indicates whether or not the values in this object are valid.
* @author ryalbe
* @return boolean indicating validity of bean
*/
public boolean isValid() {
errorList = new ArrayList(); // clear list of errors
// validate fields
validateCode();
validateName();
validateType();
validateOneOffer();
validateAdminLevel();
validatePublicOnsite();
validateInvoiceCredit();
validateStartDate();
validateEndDate();
// if list is not empty, there are errors--return false
if( !errorList.isEmpty() ) { return false; }
return true; // list is empty, return true
}
/**
* Returns the errorList for this bean.
* @author ryalbe
* @return the errorList for this bean.
*/
public List getErrorList() {
return errorList;
}
/**
* Overload of toString method.
* @author ryalbe
*/
public String toString() {
String beanString = "";
beanString += "Bean: DiscountProgram\n";
beanString += "ID: " + getID() + "\n";
beanString += "Code: " + getCode() + "\n";
beanString += "Name: " + getName() + "\n";
beanString += "Type: " + getType() + "\n";
beanString += "One Offer: " + getOneOffer() + "\n";
beanString += "Admin Level: " + getAdminLevel() + "\n";
beanString += "Public/Onsite: " + getPublicOnsite() + "\n";
beanString += "Invoice/Credit: " + getInvoiceCredit() + "\n";
beanString += "Start Date: " + DateFormats.dateFormatSAS(getStartDate()) + "\n";
beanString += "End Date: " + DateFormats.dateFormatSAS(getEndDate()) + "\n";
beanString += "Created: " + DateFormats.dateFormatSAS(getCreated()) + " " + DateFormats.timeFormat24Full(getCreated()) + "\n";
beanString += "Created By: " + getCreatedByName() + "\n";
beanString += "Last Updated: " + DateFormats.dateFormatSAS(getLastUpdated()) + " " + DateFormats.timeFormat24Full(getLastUpdated()) + "\n";
beanString += "LastUpdatedBy: " + getLastUpdatedByName() + "\n";
return beanString;
}
}
Servlet code for bean population
/**
* Populates and returns a DiscountProgram bean with data from the request.
*/
private DiscountProgram loadDiscountProgramBean( HttpServletRequest req ) {
DiscountProgram discountProgram = null; // DiscountProgram object that will hold data to be persisted to the db
if( (discountProgram = (DiscountProgram)req.getSession().getAttribute("discountProgram")) == null ) { discountProgram = new DiscountProgram(); }
discountProgram.setID( req.getParameter("discountProgramID") ); // add the id
discountProgram.setCode( req.getParameter("code") ); // add the code
discountProgram.setName( req.getParameter("name") ); // add the name
discountProgram.setType( req.getParameter("type") ); // add the type flag
discountProgram.setOneOffer( req.getParameter("oneOffer") ); // add the oneOffer flag
discountProgram.setAdminLevel( req.getParameter("adminLevel") ); // add the adminLevel flag
discountProgram.setPublicOnsite( req.getParameter("publicOnsite") ); // add the publicOnsite flag
discountProgram.setInvoiceCredit( req.getParameter("invoiceCredit") ); // add the invoiceCredit flag
/* Set startDate and endDate (if specified) */
if( DataValidator.validInt(req.getParameter("startMonth")) && DataValidator.validInt(req.getParameter("startDay")) && DataValidator.validInt(req.getParameter("startYear")) ) {
discountProgram.setStartDate( new GregorianCalendar( Integer.parseInt(req.getParameter("startYear")), Integer.parseInt(req.getParameter("startMonth")), Integer.parseInt(req.getParameter("startDay")) ) );
}
if( DataValidator.validInt(req.getParameter("endMonth")) && DataValidator.validInt(req.getParameter("endDay")) && DataValidator.validInt(req.getParameter("endYear")) ) {
discountProgram.setEndDate( new GregorianCalendar( Integer.parseInt(req.getParameter("endYear")), Integer.parseInt(req.getParameter("endMonth")), Integer.parseInt(req.getParameter("endDay")) ) );
}
// set up audit fields (values in the parameters should be correct)
if( discountProgram.getID() == null ) {
discountProgram.setCreated( Calendar.getInstance() ); // add date the record was created
discountProgram.setCreatedBy( req.getRemoteUser() ); // add the user who created the record
discountProgram.setLastUpdated( Calendar.getInstance() ); // add the date the record was last updated
}
discountProgram.setLastUpdatedBy( req.getRemoteUser() ); // add the user who last updated the record
log.info( discountProgram.toString() );
return discountProgram;
}
Code between sessionFactory.openSession() and session.close():
/**
* Updates a DiscountProgram record in the data.
* @param discountProgram - bean representing record to be added.
* @throws DBUpdateException
*/
public void updateDiscountProgram( DiscountProgram discountProgram ) throws DBUpdateException {
Session session = null; // Hibernate session used to read the data
// get a connection and add the record to the db
try {
session = HibernateSessionUtil.getSession(); // get a session for this thread
HibernateSessionUtil.beginTransaction(); // begin a transaction
log.info( "Before update: " + discountProgram.toString() );
session.update( discountProgram ); // update the DiscountProgram
log.info( "After update: " + discountProgram.toString() );
HibernateSessionUtil.commitTransaction();
}
catch( HibernateException he ) {
HibernateSessionUtil.rollbackTransaction();
throw new DBUpdateException( "Discount Program update failure: " + he.toString(), discountProgram );
}
finally {
HibernateSessionUtil.closeSession();
}
}
Full stack trace of any exception that occurs:
12:08:35,724 ERROR StandardWrapper[/EduCentral:AddUpdateDiscountProgram]:276 - Servlet.service() for servlet AddUpdateDiscountProgram threw exception
com.sas.edu.educentral.exceptions.hibernate.HibernateTransactionException: net.sf.hibernate.PropertyValueException: not-null property references a null or transient value: com.sas.edu.educentral.edusa.beans.DiscountProgram.lastUpdated
at com.sas.edu.educentral.system.dbaccess.HibernateSessionUtil.commitTransaction(Unknown Source)
at com.sas.edu.educentral.edusa.data.DiscountProgramData.updateDiscountProgram(Unknown Source)
at com.sas.edu.educentral.edusa.domain.DiscountProgramManager.updateDiscountProgram(Unknown Source)
at com.sas.edu.educentral.edusa.servlets.admin.DiscountProgramEditor.updateDiscountProgram(Unknown Source)
at com.sas.edu.educentral.edusa.servlets.admin.DiscountProgramEditor.doPost(Unknown Source)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:526)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:306)
at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:385)
at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:745)
at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:675)
at org.apache.jk.common.SocketConnection.runIt(ChannelSocket.java:868)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Unknown Source)
Caused by: net.sf.hibernate.PropertyValueException: not-null property references a null or transient value: com.sas.edu.educentral.edusa.beans.DiscountProgram.lastUpdated
at net.sf.hibernate.impl.SessionImpl.checkNullability(SessionImpl.java:1286)
at net.sf.hibernate.impl.SessionImpl.flushEntity(SessionImpl.java:2591)
at net.sf.hibernate.impl.SessionImpl.flushEntities(SessionImpl.java:2478)
at net.sf.hibernate.impl.SessionImpl.flushEverything(SessionImpl.java:2280)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2259)
at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
... 23 more
|