persistence@glassfish.java.net

Re: PrePersist method not being called

From: Wonseok Kim <guruwons_at_gmail.com>
Date: Tue, 9 Jan 2007 09:56:11 +0900

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