I have a persistent class with the dynamic-insert set to the true. In some cases, I have columns that may have null values but need to be included in the insert statement (yet there are other columns in the same class that should not be included). You see, I have "default" behaviors built into the database for many of the columns. There are a few cases where I'd rather insert a "null" rather than get the "default" database behavior (i.e. CURRENT_TIMETSTAMP as seen in SQL Server).
So in my mapping file, I have specified insert="true" to specify which attributes should be included (and override the dynamic-insert class property). Unfortunately, this doesn't work. Is this a bug?
Hibernate version: 3.0
Mapping documents:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
>
<class
name="myapp.db.DatabaseTimeObject"
table="myapp_databasetime"
dynamic-insert="true"
>
<id
name="id"
column="id"
type="long"
unsaved-value="-1"
>
<generator class="native">
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-DatabaseTimeObject.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>
<property
name="timestamp"
type="java.util.Date"
update="true"
insert="false"
column="timestamp"
/>
<property
name="trash"
type="java.lang.String"
update="true"
insert="true"
column="trash"
length="1"
/>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-DatabaseTimeObject.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>
Java documents:Code:
package myapp.db;
import java.util.Date;
/**
* Used to query the database for its current time.
*
* @hibernate.class table="myapp_databasetime" dynamic-insert="true"
*/
public class DatabaseTimeObject extends HibernateIDObject {
private Date timestamp;
private String trash;
/**
* Gets the database time.
*
* @return a time stamp
*
* @hibernate.property insert="false"
*/
public Date getTimestamp() {
return timestamp;
}
/**
* Sets the time stamp. This should not be used by the model. This
* operation is only provided to support Hibernate's ability to
* populate this object with the value read from the database.
*
* @param timestamp time in database
*/
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
/**
* Gets the trash value
*
* @return a trash value
*
* @hibernate.property insert="true" length="1"
*/
public String getTrash() {
return trash;
}
/**
* Sets the trash value. You have to have something to insert.
* Value set is ignored.
*
* @param trash trash value
*/
public void setTrash(String trash) {
// ignore value being set
}
}
Code between sessionFactory.openSession() and session.close():Code:
DatabaseTimeObject object = new DatabaseTimeObject();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.save(object);
tx.commit();
} catch (Exception ex) {
if (tx != null) {
tx.rollback();
}
}
Full stack trace of any exception that occurs:Code:
2005-12-11 06:00:23,243 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 170, SQLState: 37000
2005-12-11 06:00:23,243 [main] ERROR org.hibernate.util.JDBCExceptionReporter - Line 1: Incorrect syntax near ')'.
2005-12-11 06:00:24,430 [main] ERROR wintox.db.HibernateAdapter - could not save object [wintox.db.DatabaseTimeObject@f]
org.hibernate.exception.SQLGrammarException: could not insert: [wintox.db.DatabaseTimeObject]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:59)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1777)
at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:2171)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:34)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:240)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:160)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:95)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:184)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:173)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:69)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:481)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:476)
at wintox.db.HibernateAdapter.saveObject(HibernateAdapter.java:207)
at wintox.db.DatabaseTime.getDatabaseTime(DatabaseTime.java:16)
at wintox.audit.user.UserAuditManager.auditUserLogin(UserAuditManager.java:53)
at wintox.orderentry.security.SecurityManagerImpl.loginUser(SecurityManagerImpl.java:365)
at wintox.orderentry.model.UserAccessModel.validateLogin(UserAccessModel.java:217)
at wintoxplugin.Application.authenticate(Application.java:158)
at wintoxplugin.Application.run(Application.java:114)
at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:226)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:376)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:163)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.eclipse.core.launcher.Main.invokeFramework(Main.java:334)
at org.eclipse.core.launcher.Main.basicRun(Main.java:278)
at org.eclipse.core.launcher.Main.run(Main.java:973)
at org.eclipse.core.launcher.Main.main(Main.java:948)
Caused by: java.sql.SQLException: Line 1: Incorrect syntax near ')'.
at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:365)
at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2781)
at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2224)
at net.sourceforge.jtds.jdbc.TdsCore.getMoreResults(TdsCore.java:628)
at net.sourceforge.jtds.jdbc.JtdsStatement.processResults(JtdsStatement.java:525)
at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQL(JtdsStatement.java:487)
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeUpdate(JtdsPreparedStatement.java:421)
at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1759)
... 31 more
Name and version of the database you are using:SQL Server 2000
The generated SQL (show_sql=true):Hibernate: insert into wintox_databasetime values ( )
Debug level Hibernate log excerpt:Additional info:
Code:
CREATE TABLE wintox_databasetime (
id numeric(19,0) identity NOT NULL,
timestamp datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
trash varchar(1) NULL,
primary key (id));