persistence@glassfish.java.net

Re: PrePersist method not being called

From: Jon Miller <jemiller_at_uchicago.edu>
Date: Mon, 8 Jan 2007 15:38:50 -0600

Basically, I'm just doing a merge. EntityManagerHelper is a class that I
wrote which creates an EntityManagerFactory and EntityManager and stores it
in a ThreadLocal. I can probably package things up and send it to you if you
want.

    public User saveUser(User user) {
        logger.fine("entered");
        if (user == null)
        {
            throw new IllegalArgumentException("user must not be null");
        }
        ...
        EntityManager em = EntityManagerHelper.getEntityManager();
        EntityTransaction et = em.getTransaction();
        et.begin();
        user = em.merge(user);
        et.commit();
        ...

Jon

----- Original Message -----
From: "Guy Pelletier" <guy.pelletier_at_oracle.com>
To: <persistence_at_glassfish.dev.java.net>
Sent: Monday, January 08, 2007 3:19 PM
Subject: Re: PrePersist method not being called


> Hi Jon,
>
> No, that should be fine. Can you provide a snippet of the code that are
> you executing, that should cause the pre-persist event to be called?
>
> Cheers,
> Guy
>
> ----- Original Message -----
> From: "Jon Miller" <jemiller_at_uchicago.edu>
> To: <persistence_at_glassfish.dev.java.net>
> Sent: Monday, January 08, 2007 4:08 PM
> Subject: Re: PrePersist method not being called
>
>
>> Guy, yes, I just noticed that preUpdate is called. It's just prePersist
>> that isn't being called. Another thing that just occurred to me. I don't
>> know if this has anything to do with it or not, but, the Id value for the
>> class is implemented in the subclasses, not AuditObject. So, AuditObject
>> has a PrePersist method but no Id field. I'm guessing maybe that's it?
>> AuditObject is an abstract class.
>>
>> Jon
>>
>> ----- Original Message -----
>> From: "Guy Pelletier" <guy.pelletier_at_oracle.com>
>> To: <persistence_at_glassfish.dev.java.net>
>> Sent: Monday, January 08, 2007 12:20 PM
>> Subject: Re: PrePersist method not being called
>>
>>
>>> Hi Jon,
>>>
>>> I noticed there is a pre-update listener on the mapped superclass. Does
>>> it ever get called? Is it just the pre-persist that never executes?
>>>
>>> Cheers,
>>> Guy
>>>
>>> ----- Original Message -----
>>> From: "Jon Miller" <jemiller_at_uchicago.edu>
>>> To: <persistence_at_glassfish.dev.java.net>
>>> Sent: Monday, January 08, 2007 1:00 PM
>>> Subject: Re: PrePersist method not being called
>>>
>>>
>>>> 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
>>>>>>>>>>
>>>>>>>>>>
>>>>>
>>>>
>>>
>>
>