persistence@glassfish.java.net

Re: PrePersist method not being called

From: Tom Ware <tom.ware_at_oracle.com>
Date: Thu, 11 Jan 2007 13:30:37 -0500

Hi Jon,

  You are correct, TopLink Essentials' weaving code alters the classes
themselves.

-Tom

Jon Miller wrote:

>One other thing I've been wondering about. I'm guessing the runtime weaving
>that the javaagent does works differently than how it works in Hibernate. I
>think in Hibernate it creates subclasses of your class on the fly. But, it
>sounds like TopLink, alters the classes themselves (i.e. it doesn't create a
>subclass, it changes the class itself)?
>
>I'm guessing that eventually I starting using build-time weaving. One of the
>things that I've always disliked about Hibernate is the slow startup time.
>>From what I remember, Hibernate doesn't have a build-time way to do it.
>
>Jon
>
>----- Original Message -----
>From: "Wonseok Kim" <guruwons_at_gmail.com>
>To: <persistence_at_glassfish.dev.java.net>
>Sent: Monday, January 08, 2007 6:56 PM
>Subject: Re: PrePersist method not being called
>
>
>
>
>>Hi Jon,
>>Spring framework provides Java EE 5 container-like features for Tomcat
>>container so that dynamic weaving can occur in Tomcat's classloader. With
>>this you can avoid VM agent option. Please see the following
>>documentation.
>>http://static.springframework.org/spring/docs/2.0.x/reference/orm.html#orm-jpa-setup-lcemfb
>>
>>Cheers,
>>-Wonseok
>>
>>On 1/9/07, Jon Miller <jemiller_at_uchicago.edu> wrote:
>>
>>
>>>Thanks Tom. Yeah, I have all the classes listed there now. It still isn't
>>>working though. I just tried a simpler test with the PrePersist method in
>>>the top level class and it worked. I'll have to look into it further...
>>>
>>>Thanks for the info on weaving. I recently read about that. So far I just
>>>been doing without it. I figure once I get further along I may need to
>>>enable it if performance is an issue. One thing that I'm wondering about
>>>the
>>>agent is: is it possible to somehow enable the agent programatically in
>>>the
>>>program itself, or, does it have to be passed as a command-line argument?
>>>I'm using TopLink with Tomcat and not using an EJB application server. I
>>>like the idea of being able to deploy the web app self-contained without
>>>having to make changes to the web server configuration such as passing
>>>command-line arguments to the JVM.
>>>
>>>Jon
>>>
>>>----- Original Message -----
>>>From: "Tom Ware" <tom.ware_at_oracle.com>
>>>To: <persistence_at_glassfish.dev.java.net>
>>>Sent: Monday, January 08, 2007 8:28 AM
>>>Subject: Re: PrePersist method not being called
>>>
>>>
>>>
>>>
>>>>Hi Jon,
>>>>
>>>> Are you still seeing the problem now that you have listed AuditObject
>>>>
>>>>
>>>in
>>>
>>>
>>>>your persistence.xml?
>>>>
>>>>In Java SE, the JPA specification says that portable applications must
>>>>list the classes that will be used in the persistence.xml either with
>>>><class> element, by referring to them in a file referenced by a
>>>><mapping-file> element, or by placing them in a file referenced by a
>>>><jar-file> element. As a result, in Java SE depending on how your
>>>>persistence.xml looks, we may not automatically discover your classes.
>>>>
>>>> In some Java SE Environments TopLink Essentials will be able to
>>>>auto-discover if you use the <exclude-unlisted-classes> element in your
>>>>persistence.xml and set it to false.
>>>>
>>>> FYI: You have asked a couple of questions about the javaagent, so
>>>>I'll
>>>>give you an idea what the purpose of the agent is. In TopLink
>>>>
>>>>
>>>Essentials,
>>>
>>>
>>>>we use the javaagent to dynamically weave classes that have OneToOne or
>>>>ManyToOne mappings with FetchType LAZY. The weaving allows us to
>>>>
>>>>
>>>actually
>>>
>>>
>>>>retrieve the elements referenced by those mappings in a LAZY
>>>>
>>>>
>>>manner. For
>>>
>>>
>>>>those that do not wish to use the agent (or cannot use it), there is
>>>>
>>>>
>>>also
>>>
>>>
>>>>the option of using a preprocessing step for this weaving. If you are
>>>>interested in that step, take a look at the section of the following
>>>>document entitled, "Static Weaving Using the StaticWeave Class on the
>>>>Command Line":
>>>>
>>>>
>>>>
>>>>
>>>http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-extensions.html#LazyLoading
>>>
>>>
>>>>-Tom
>>>>
>>>>Jon Miller wrote:
>>>>
>>>>
>>>>
>>>>>I thought I found what might have been the problem on my side. I wasn't
>>>>>listing AuditObject in my persistence.xml. Initially, I was thinking
>>>>>
>>>>>
>>>that
>>>
>>>
>>>>>you only would have to list the subclasses that you are using directly
>>>>>
>>>>>
>>>and
>>>
>>>
>>>>>that it would automatically add in the superclasses for you. I found
>>>>>out
>>>>>that this doesn't appear to be the case though (at least in standalone
>>>>>mode). Another thing worth mentioning is that the AuditObject class is
>>>>>
>>>>>
>>>in
>>>
>>>
>>>>>a different jar file. I'm not sure if that would make a difference or
>>>>>
>>>>>
>>>not.
>>>
>>>
>>>>>There's only one persistence.xml, but, the classes are split between
>>>>>two
>>>>>jar files.
>>>>>
>>>>>Jon
>>>>>
>>>>>----- Original Message -----
>>>>>From: "Jon Miller" <jemiller_at_uchicago.edu>
>>>>>To: <persistence_at_glassfish.dev.java.net>
>>>>>Sent: Friday, January 05, 2007 6:13 PM
>>>>>Subject: Re: PrePersist method not being called
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>OK, I tested it and it works with Hibernate, but, I receive the
>>>>>>
>>>>>>
>>>following
>>>
>>>
>>>>>>error with TopLink. The prePersist method is supposed to be called
>>>>>>
>>>>>>
>>>which
>>>
>>>
>>>>>>sets the lastWriteTime field. This isn't happening, so, it's causing
>>>>>>an
>>>>>>exception since that field is NOT NULL.
>>>>>>
>>>>>> [junit] Caused by: Exception [TOPLINK-4002] (Oracle TopLink
>>>>>>Essentials - 9.1 (Build b30)): oracle.toplink.essentials
>>>>>>.exceptions.DatabaseException
>>>>>> [junit] Internal Exception: java.sql.SQLException:
>>>>>>[SKATE\SQLEXPRESS]Cannot insert the value NULL into column 'LastW
>>>>>>riteTime', table 'Schedules.dbo.Person'; column does not allow nulls.
>>>>>>INSERT fails.Error Code: 515
>>>>>> [junit] Call:INSERT INTO Person (Department, CreationUserName,
>>>>>>FirstName, LastName, LastWriteTime, Name, LastWriteUs
>>>>>>erName, MiddleName, TelephoneNumber, Title, CreationTime, Curriculum,
>>>>>>Address, UserName, EmailAddress, Organization, Cla
>>>>>>ss) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
>>>>>> [junit] bind => [null, null, Jonathan, Miller, null, Jonathan
>>>>>>
>>>>>>
>>>Eric
>>>
>>>
>>>>>>Miller, null, Eric, null, null, null, null, n
>>>>>>ull, jemiller, null, null, Schedules.Persistence.Entity.User]
>>>>>>
>>>>>>Jon
>>>>>>
>>>>>>----- Original Message -----
>>>>>>From: "Jon Miller" <jemiller_at_uchicago.edu>
>>>>>>To: <persistence_at_glassfish.dev.java.net>
>>>>>>Sent: Friday, January 05, 2007 5:47 PM
>>>>>>Subject: Re: PrePersist method not being called
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>OK, I tested it with V2 build 30. It still isn't getting called. I'm
>>>>>>>
>>>>>>>
>>>not
>>>
>>>
>>>>>>>using the agent at present. Would that matter? I'm wondering if the
>>>>>>>problem is that the PrePersist method is in a MappedSuperclass? I
>>>>>>>
>>>>>>>
>>>think
>>>
>>>
>>>>>>>that's a valid thing to do though. I think the Javadocs mention it if
>>>>>>>
>>>>>>>
>>>I
>>>
>>>
>>>>>>>remember correctly. I'm going to test it again with Hibernate, just
>>>>>>>to
>>>>>>>make sure I'm not doing something else wrong and that it does indeed
>>>>>>>work with Hibernate and not TopLink.
>>>>>>>
>>>>>>>Jon
>>>>>>>
>>>>>>>----- Original Message -----
>>>>>>>From: "Tom Ware" <tom.ware_at_oracle.com>
>>>>>>>To: <persistence_at_glassfish.dev.java.net>
>>>>>>>Sent: Thursday, January 04, 2007 2:10 PM
>>>>>>>Subject: Re: PrePersist method not being called
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>Hi Jon,
>>>>>>>>
>>>>>>>>Do you see the same behavior on the latest builds of TopLink
>>>>>>>>essentials (e.g. V2 build 30)? There have been quite a lot of
>>>>>>>>
>>>>>>>>
>>>changes
>>>
>>>
>>>>>>>>since the end of August (060830).
>>>>>>>>
>>>>>>>>You can get the latest version at:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>https://glassfish.dev.java.net/downloads/persistence/JavaPersistence.html
>>>
>>>
>>>>>>>>-Tom
>>>>>>>>
>>>>>>>>Jon Miller wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>>Hi all,
>>>>>>>>>
>>>>>>>>>I'm using the version of Toplink Essentials that comes with
>>>>>>>>>NetBeans
>>>>>>>>>5.5. I have a class which defines a PrePersist method
>>>>>>>>>(AuditObject.prePersist()) which sets some values in an object
>>>>>>>>>
>>>>>>>>>
>>>(namely
>>>
>>>
>>>>>>>>>a timestamp which is a NOT NULL value). I'm finding that this
>>>>>>>>>method
>>>>>>>>>isn't being called when I attempt to persist an Item object
>>>>>>>>>
>>>>>>>>>
>>>(subclass
>>>
>>>
>>>>>>>>>of AuditObject). It works fine if I use Hibernate's implementation
>>>>>>>>>
>>>>>>>>>
>>>of
>>>
>>>
>>>>>>>>>JPA. Does anyone know what I might be doing wrong or if this is a
>>>>>>>>>known issue? So far I haven't been using the javaagent. However, I
>>>>>>>>>just tried it with the agent to see if that might be the problem,
>>>>>>>>>
>>>>>>>>>
>>>but,
>>>
>>>
>>>>>>>>>it didn't make a difference. The following is the exception that
>>>>>>>>>I'm
>>>>>>>>>receiving.
>>>>>>>>>
>>>>>>>>>Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2006.8 (Build
>>>>>>>>>060830)): oracle.toplink.essentials.exceptions.DatabaseException
>>>>>>>>>Internal Exception: java.sql.SQLException: [SKATE\SQLEXPRESS]Cannot
>>>>>>>>>insert the value NULL into column 'LastWriteTime', table
>>>>>>>>>'ReservationsDev.dbo.Item'; column does not allow nulls. INSERT
>>>>>>>>>fails.Error Code: 515
>>>>>>>>>Call:INSERT INTO Item (Name, CreationUserName, Description,
>>>>>>>>>LastWriteUserName, LastWriteTime, CreationTime) VALUES (?, ?, ?, ?,
>>>>>>>>>
>>>>>>>>>
>>>?,
>>>
>>>
>>>>>>>>>?)
>>>>>>>>> bind => [testSaveItem Wed Jan 03 14:43:08 CST 2007, null,
>>>>>>>>>Description, null, null, null]
>>>>>>>>>Query:InsertObjectQuery([id = null, name = "testSaveItem Wed Jan 03
>>>>>>>>>14:43:08 CST 2007", description = "Description"])
>>>>>>>>>javax.persistence.RollbackException: Exception [TOPLINK-4002]
>>>>>>>>>
>>>>>>>>>
>>>(Oracle
>>>
>>>
>>>>>>>>>TopLink Essentials - 2006.8 (Build 060830)):
>>>>>>>>>oracle.toplink.essentials.exceptions.DatabaseException
>>>>>>>>>Internal Exception: java.sql.SQLException: [SKATE\SQLEXPRESS]Cannot
>>>>>>>>>insert the value NULL into column 'LastWriteTime', table
>>>>>>>>>'ReservationsDev.dbo.Item'; column does not allow nulls. INSERT
>>>>>>>>>fails.Error Code: 515
>>>>>>>>>Call:INSERT INTO Item (Name, CreationUserName, Description,
>>>>>>>>>LastWriteUserName, LastWriteTime, CreationTime) VALUES (?, ?, ?, ?,
>>>>>>>>>
>>>>>>>>>
>>>?,
>>>
>>>
>>>>>>>>>?)
>>>>>>>>> bind => [testSaveItem Wed Jan 03 14:43:08 CST 2007, null,
>>>>>>>>>Description, null, null, null]
>>>>>>>>>Query:InsertObjectQuery([id = null, name = "testSaveItem Wed Jan 03
>>>>>>>>>14:43:08 CST 2007", description = "Description"])
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.ejb.cmp3.transaction.base.EntityTransactionImpl.commit
>>>(EntityTransactionImpl.java:109)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.ejb.cmp3.transaction.EntityTransactionImpl.commit
>>>(EntityTransactionImpl.java:45)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>edu.uchicago.at.reservations.ReservationsService.saveItem(
>>>>>>>>>
>>>>>>>>>
>>>ReservationsService.java:254)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>edu.uchicago.at.reservations.ReservationsServiceTest.testSaveGetAndRemoveItem
>>>(ReservationsServiceTest.java:44)
>>>
>>>
>>>>>>>>>Caused by: Exception [TOPLINK-4002] (Oracle TopLink Essentials -
>>>>>>>>>2006.8 (Build 060830)):
>>>>>>>>>oracle.toplink.essentials.exceptions.DatabaseException
>>>>>>>>>Internal Exception: java.sql.SQLException: [SKATE\SQLEXPRESS]Cannot
>>>>>>>>>insert the value NULL into column 'LastWriteTime', table
>>>>>>>>>'ReservationsDev.dbo.Item'; column does not allow nulls. INSERT
>>>>>>>>>fails.Error Code: 515
>>>>>>>>>Call:INSERT INTO Item (Name, CreationUserName, Description,
>>>>>>>>>LastWriteUserName, LastWriteTime, CreationTime) VALUES (?, ?, ?, ?,
>>>>>>>>>
>>>>>>>>>
>>>?,
>>>
>>>
>>>>>>>>>?)
>>>>>>>>> bind => [testSaveItem Wed Jan 03 14:43:08 CST 2007, null,
>>>>>>>>>Description, null, null, null]
>>>>>>>>>Query:InsertObjectQuery([id = null, name = "testSaveItem Wed Jan 03
>>>>>>>>>14:43:08 CST 2007", description = "Description"])
>>>>>>>>> at
>>>>>>>>>oracle.toplink.essentials.exceptions.DatabaseException.sqlException
>>>>>>>>>
>>>>>>>>>
>>>(DatabaseException.java:295)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect
>>>(DatabaseAccessor.java:639)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeNoSelect
>>>(DatabaseAccessor.java:688)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicExecuteCall
>>>(DatabaseAccessor.java:477)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeCall
>>>(DatabaseAccessor.java:437)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.sessions.AbstractSession.executeCall(
>>>AbstractSession.java:675)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall
>>>(DatasourceCallQueryMechanism.java:213)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall
>>>(DatasourceCallQueryMechanism.java:199)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.insertObject
>>>(DatasourceCallQueryMechanism.java:331)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.queryframework.StatementQueryMechanism.insertObject
>>>(StatementQueryMechanism.java:176)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.queryframework.StatementQueryMechanism.insertObject
>>>(StatementQueryMechanism.java:190)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.insertObjectForWrite
>>>(DatabaseQueryMechanism.java:457)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.queryframework.InsertObjectQuery.executeCommit(
>>>InsertObjectQuery.java:74)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.performUserDefinedWrite
>>>(DatabaseQueryMechanism.java:635)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.performUserDefinedInsert
>>>(DatabaseQueryMechanism.java:599)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.insertObjectForWriteWithChangeSet
>>>(DatabaseQueryMechanism.java:495)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.queryframework.WriteObjectQuery.executeCommitWithChangeSet
>>>(WriteObjectQuery.java:130)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.executeWriteWithChangeSet
>>>(DatabaseQueryMechanism.java:283)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.queryframework.WriteObjectQuery.executeDatabaseQuery
>>>(WriteObjectQuery.java:67)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>oracle.toplink.essentials.queryframework.DatabaseQuery.execute(
>>>>>>>>>
>>>>>>>>>
>>>DatabaseQuery.java:609)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.queryframework.DatabaseQuery.executeInUnitOfWork
>>>(DatabaseQuery.java:536)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery
>>>(ObjectLevelModifyQuery.java:123)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWork
>>>(ObjectLevelModifyQuery.java:95)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery
>>>(UnitOfWorkImpl.java:2218)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(
>>>AbstractSession.java:937)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(
>>>AbstractSession.java:894)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet
>>>(CommitManager.java:254)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.sessions.CommitManager.commitAllObjectsWithChangeSet
>>>(CommitManager.java:175)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet
>>>(AbstractSession.java:2638)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabase
>>>(UnitOfWorkImpl.java:1030)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.commitToDatabase
>>>(RepeatableWriteUnitOfWork.java:357)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet
>>>(UnitOfWorkImpl.java:1112)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.commitRootUnitOfWork
>>>(RepeatableWriteUnitOfWork.java:82)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitAndResume
>>>(UnitOfWorkImpl.java:842)
>>>
>>>
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.ejb.cmp3.transaction.base.EntityTransactionImpl.commit
>>>(EntityTransactionImpl.java:90)
>>>
>>>
>>>>>>>>> ... 18 more
>>>>>>>>>Caused by: java.sql.SQLException: [SKATE\SQLEXPRESS]Cannot insert
>>>>>>>>>
>>>>>>>>>
>>>the
>>>
>>>
>>>>>>>>>value NULL into column 'LastWriteTime', table
>>>>>>>>>'ReservationsDev.dbo.Item'; column does not allow nulls. INSERT
>>>>>>>>>
>>>>>>>>>
>>>fails.
>>>
>>>
>>>>>>>>> at com.inet.tds.a.a(Unknown Source)
>>>>>>>>> at com.inet.tds.c.new(Unknown Source)
>>>>>>>>> at com.inet.tds.c.executeUpdate(Unknown Source)
>>>>>>>>> at
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect
>>>(DatabaseAccessor.java:632)
>>>
>>>
>>>>>>>>> ... 51 more
>>>>>>>>>
>>>>>>>>>// AuditObject.java
>>>>>>>>>package edu.uchicago.at.common.persistence.entity;
>>>>>>>>>
>>>>>>>>>import java.io.Serializable;
>>>>>>>>>import java.util.Date;
>>>>>>>>>import java.util.logging.Logger;
>>>>>>>>>import javax.persistence.Column;
>>>>>>>>>import javax.persistence.MappedSuperclass;
>>>>>>>>>import javax.persistence.PrePersist;
>>>>>>>>>import javax.persistence.PreUpdate;
>>>>>>>>>import javax.persistence.Temporal;
>>>>>>>>>import javax.persistence.TemporalType;
>>>>>>>>>
>>>>>>>>>@MappedSuperclass
>>>>>>>>>public abstract class AuditObject implements Serializable {
>>>>>>>>> private Date creationTime;
>>>>>>>>> private String creationUserName;
>>>>>>>>> private Date lastWriteTime;
>>>>>>>>> private String lastWriteUserName;
>>>>>>>>> private static Logger logger = Logger.getLogger(
>>>>>>>>> AuditObject.class.getName());
>>>>>>>>>
>>>>>>>>> @Column(name="CreationTime", nullable=false)
>>>>>>>>> @Temporal(TemporalType.TIMESTAMP)
>>>>>>>>> public Date getCreationTime() {
>>>>>>>>> return creationTime;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> public void setCreationTime(Date creationTime) {
>>>>>>>>> this.creationTime = creationTime;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> @Column(name="CreationUserName",
>>>>>>>>>
>>>>>>>>>
>>>columnDefinition="nvarchar(255)")
>>>
>>>
>>>>>>>>> public String getCreationUserName() {
>>>>>>>>> return creationUserName;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> public void setCreationUserName(String creationUserName) {
>>>>>>>>> this.creationUserName = creationUserName;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> @Column(name="LastWriteTime", nullable=false)
>>>>>>>>> @Temporal(TemporalType.TIMESTAMP)
>>>>>>>>> public Date getLastWriteTime() {
>>>>>>>>> return lastWriteTime;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> public void setLastWriteTime(Date lastWriteTime) {
>>>>>>>>> this.lastWriteTime = lastWriteTime;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> @Column(name="LastWriteUserName",
>>>>>>>>>
>>>>>>>>>
>>>columnDefinition="nvarchar(255)")
>>>
>>>
>>>>>>>>> public String getLastWriteUserName() {
>>>>>>>>> return lastWriteUserName;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> public void setLastWriteUserName(String lastWriteUserName) {
>>>>>>>>> this.lastWriteUserName = lastWriteUserName;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> @PrePersist
>>>>>>>>> public void prePersist() {
>>>>>>>>> Date d = new Date();
>>>>>>>>> setCreationTime(d);
>>>>>>>>> setLastWriteTime(d);
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> @PreUpdate
>>>>>>>>> public void preUpdate() {
>>>>>>>>> Date d = new Date();
>>>>>>>>> setLastWriteTime(d);
>>>>>>>>> }
>>>>>>>>>}
>>>>>>>>>
>>>>>>>>>// Item.java
>>>>>>>>>package edu.uchicago.at.reservations.persistence.entity;
>>>>>>>>>
>>>>>>>>>import edu.uchicago.at.common.persistence.entity.AuditObject;
>>>>>>>>>import java.util.ArrayList;
>>>>>>>>>import java.util.Collection;
>>>>>>>>>import javax.persistence.Column;
>>>>>>>>>import javax.persistence.Entity;
>>>>>>>>>import javax.persistence.GeneratedValue;
>>>>>>>>>import javax.persistence.GenerationType;
>>>>>>>>>import javax.persistence.Id;
>>>>>>>>>import javax.persistence.JoinColumn;
>>>>>>>>>import javax.persistence.JoinTable;
>>>>>>>>>import javax.persistence.ManyToMany;
>>>>>>>>>import javax.persistence.Table;
>>>>>>>>>
>>>>>>>>>@Entity
>>>>>>>>>@Table(name="Item")
>>>>>>>>>public class Item extends AuditObject {
>>>>>>>>> private String description;
>>>>>>>>> private Integer id;
>>>>>>>>> private String name;
>>>>>>>>> private Collection<Reservation> reservations = new
>>>>>>>>>ArrayList<Reservation>();
>>>>>>>>> private Collection<Item> subItems = new ArrayList<Item>();
>>>>>>>>> private Collection<Item> superItems = new ArrayList<Item>();
>>>>>>>>>
>>>>>>>>> public Item() {
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> public Item(String name) {
>>>>>>>>> setName(name);
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> public boolean contains(Item item) {
>>>>>>>>> for(Item i : subItems) {
>>>>>>>>> if (i.id == item.id) {
>>>>>>>>> return true;
>>>>>>>>> }
>>>>>>>>> if (i.contains(item)) {
>>>>>>>>> return true;
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>> return false;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> @Column(name="Description", columnDefinition="nvarchar(max)")
>>>>>>>>> public String getDescription() {
>>>>>>>>> return description;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> public void setDescription(String description) {
>>>>>>>>> this.description = description;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> @Id
>>>>>>>>> @GeneratedValue(strategy = GenerationType.IDENTITY)
>>>>>>>>> @Column(name="Id")
>>>>>>>>> public Integer getId() {
>>>>>>>>> return id;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> public void setId(Integer id) {
>>>>>>>>> this.id = id;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> @Column(name="Name", columnDefinition="nvarchar(255)")
>>>>>>>>> public String getName() {
>>>>>>>>> return name;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> public void setName(String name) {
>>>>>>>>> this.name = name;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> @ManyToMany(mappedBy="items")
>>>>>>>>> public Collection<Reservation> getReservations() {
>>>>>>>>> return reservations;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> public void setReservations(Collection<Reservation>
>>>>>>>>>reservations)
>>>>>>>>>
>>>>>>>>>
>>>{
>>>
>>>
>>>>>>>>> this.reservations = reservations;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> @ManyToMany
>>>>>>>>> @JoinTable(name="ItemItem",
>>>>>>>>>joinColumns={_at_JoinColumn(name="ItemId")},
>>>>>>>>> inverseJoinColumns={_at_JoinColumn(name="SubItemId")})
>>>>>>>>> public Collection<Item> getSubItems() {
>>>>>>>>> return subItems;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> public void setSubItems(Collection<Item> subItems) {
>>>>>>>>> this.subItems = subItems;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> @ManyToMany(mappedBy="subItems")
>>>>>>>>> public Collection<Item> getSuperItems() {
>>>>>>>>> return superItems;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> public void setSuperItems(Collection<Item> superItems) {
>>>>>>>>> this.superItems = superItems;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> public String toString() {
>>>>>>>>> StringBuilder sb = new StringBuilder();
>>>>>>>>> sb.append("[");
>>>>>>>>> sb.append(String.format("id = %d", id));
>>>>>>>>> sb.append(String.format(", name = \"%s\"", name));
>>>>>>>>> sb.append(String.format(", description = \"%s\"",
>>>>>>>>>description));
>>>>>>>>> sb.append("]");
>>>>>>>>> return sb.toString();
>>>>>>>>> }
>>>>>>>>>}
>>>>>>>>>
>>>>>>>>>Jon
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>