persistence@glassfish.java.net

Re: PrePersist method not being called

From: Jon Miller <jemiller_at_uchicago.edu>
Date: Mon, 8 Jan 2007 19:00:06 -0600

Thanks for the info.

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
>> >>>>>>
>> >>>>>>
>> >
>>
>