Hi Brian, I have fixed the OTM bug (M:N relations wasn't updated). Thanks for detailed bug report.
Regards, Oleg On Tuesday 14 October 2003 14:16, Brian McCallister wrote: > On Tuesday, October 14, 2003, at 09:33 AM, [EMAIL PROTECTED] wrote: > > Hej Brian, > > > >> -----Original Message----- > >> From: Brian McCallister [mailto:[EMAIL PROTECTED] > >> > >> I have mixed and matched the value, but it hasn't mattered. I had > >> thought it might care so I tried various combinations. It in > >> this vase > >> being a nebulous entity who thwarts my plans, as to my knowledge > >> neither OJB nor Postgres care about case of table names. > > > > Which API do you use? > > OTM (with OQL and Iterators instead of DLists -- see findById(...) > below ). The project is part of my OTM learning process so I can write > some docs on it. > > > Which concrete class is instantiated > > for the list field? > > Default - I don't specify anything so should be a Vector. > > > Can you post the code that you use > > to persist the objects? > > Of course, I will put a tarball ( > http://kasparov.skife.org/kim-broken.tar.gz (includes jars so is big, 8 > megs)) of the whole project up, the relevent pieces: > > Test Failure: > --------------------------------------- > There was 1 failure: > 1) > testRequestFriend(org.skife.kim.model.TestUserRelations)junit.framework. > AssertionFailedError: expected:<1> but was:<0> > at > org.skife.kim.model.TestUserRelations.testRequestFriend(TestUserRelation > s.java:76) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.jav > a:39) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor > Impl.java:25) > at > com.intellij.rt.execution.junit.TextTestRunner.main(TextTestRunner.java: > 12) > --------------------------------------- > FAILURES!!! > Tests run: 1, Failures: 1, Errors: 0 > > The Test: (one and two are created in the setup and removed in the > teardown) > ------------------------- > public void testRequestFriend() throws Exception > { > Unit unit = Unit.begin(); > one = UserRepository.findById(one.getId(), unit); > two = UserRepository.findById(two.getId(), unit); > one.addFriend(two); > unit.commit(); > > TestTools.clearCache(); > > unit = Unit.begin(); > one = UserRepository.findById(one.getId(), unit); > List friends = one.getFriends(); > Assert.assertEquals(1, one.getFriends().size()); // This > Assertion Fails > unit.commit(); > } > --------------------------- > > Unit simply provides a convenience wrapper around OTMConnections and > Transactions: > -------------------------- > package org.skife.kim.infra; > > import org.apache.ojb.otm.core.Transaction; > import org.apache.ojb.otm.OTMConnection; > import org.apache.ojb.otm.kit.SimpleKit; > import org.apache.ojb.broker.PersistenceBrokerFactory; > > /** > * Unit of Work shortened for typing purposes > * > * TODO: Add a factory method that takes a long argument and will > rollback the transaction > * after an elapsed time has passed. Each getConnection() call > extends the time > * by the initial value. This allows for clearing the connection > before the session > * times out in web apps > */ > public class Unit > { > private Transaction transaction; > private OTMConnection connection; > > private Unit() > { > this.connection = > SimpleKit.getInstance().acquireConnection(PersistenceBrokerFactory.getDe > faultKey()); > this.transaction = > SimpleKit.getInstance().getTransaction(this.connection); > } > > public static Unit begin() > { > Unit unit = new Unit(); > unit.transaction.begin(); > return unit; > } > > /** > * @throws org.skife.kim.infra.UnitException if the Unit of Work > has already been committed > * or rolled back - either via this or the > underlying > * Transaction/OTMConnection > */ > public void commit() throws UnitException > { > if (! transaction.isInProgress()) > { > throw new UnitException("Unit of work already closed"); > } > this.transaction.commit(); > this.connection.close(); > } > > /** > * @throws org.skife.kim.infra.UnitException if the Unit of Work > has already been committed > * or rolled back - either via this or the > underlying > * Transaction/OTMConnection > */ > public void rollback() throws UnitException > { > if (! transaction.isInProgress()) > { > throw new UnitException("Unit of work already closed"); > } > this.transaction.rollback(); > this.connection.close(); > } > > /** > * @return the OTMConnection in use by this Unit. It is already > transactional > */ > OTMConnection getConnection() > { > return this.connection; > } > } > > > --------------------- > The findById(...) used to retrieve the User instances: > ------------------- > public static User findById(Integer id, Unit unit) throws > UnitException > { > try > { > EnhancedOQLQuery query = unit.getConnection().newOQLQuery(); > query.create("select allprofiles from " > + User.class.getName() > + " where id = $1"); > query.bind(id); > > User user = null; > Iterator i = > unit.getConnection().getIteratorByOQLQuery(query); > if (i.hasNext()) user = (User) i.next(); > > return user; > } > catch (Exception e) > { > throw new UnitException("Unable to find User: " + > e.getMessage(), e); > } > } > > ---------- > The User: > -------------- > package org.skife.kim.model; > > import java.io.Serializable; > import java.util.ArrayList; > import java.util.Collections; > import java.util.List; > > public class User implements Serializable > { > private List giftsRequested; > private List friends; > private String handle; > private String firstName; > private String lastName; > private String password; > private Integer id; > > > private User() > { > // For OJB > } > > public static User newUser(String handle, String password) > { > User user = new User(); > > user.handle = handle; > user.password = password; > user.giftsRequested = new ArrayList(); > user.friends = new ArrayList(); > > return user; > } > > public List getFriends() > { > return this.friends; > } > > public void addFriend(User user) > { > this.friends.add(user); > } > > public boolean removeFriend(User user) > { > return this.friends.remove(user); > } > > /** > * Gift Factory Method > */ > public Gift requestGift() > { > Gift gift = new Gift(this); > this.giftsRequested.add(gift); > return gift; > } > > public boolean removeRequestedGift(Gift gift) > { > return this.giftsRequested.remove(gift); > } > > public Integer getId() > { > return this.id; > } > > public List getGiftsRequested() > { > return Collections.unmodifiableList(this.giftsRequested); > } > > public String getHandle() > { > return handle; > } > > public String getFirstName() > { > return firstName; > } > > public void setFirstName(String firstName) > { > this.firstName = firstName; > } > > public String getLastName() > { > return lastName; > } > > public void setLastName(String lastName) > { > this.lastName = lastName; > } > > public String getPassword() > { > return password; > } > > public void setPassword(String password) > { > this.password = password; > } > } > ----------------- > The mapping: > ---------------- > <class-descriptor class="org.skife.kim.model.User" table="USERS"> > <field-descriptor name="id" column="ID" jdbc-type="INTEGER" > primarykey="true" autoincrement="true"/> > <field-descriptor name="handle" column="HANDLE" > jdbc-type="VARCHAR"/> > <field-descriptor name="password" column="PASSWORD" > jdbc-type="VARCHAR"/> > <field-descriptor name="lastName" column="LAST_NAME" > jdbc-type="VARCHAR"/> > <field-descriptor name="firstName" column="FIRST_NAME" > jdbc-type="VARCHAR"/> > > <collection-descriptor name="giftsRequested" > element-class-ref="org.skife.kim.model.Gift"> > <inverse-foreignkey field-ref="for_user_id"/> > </collection-descriptor> > > <collection-descriptor name="friends" > element-class-ref="org.skife.kim.model.User" > indirection-table="RELATIONS"> > <fk-pointing-to-this-class column="OWNER_ID"/> > <fk-pointing-to-element-class column="FRIEND_ID"/> > </collection-descriptor> > </class-descriptor> > ------------------ > The Schema: > -------------------- > <table name="relations" description="M:N mapping table for user's > friends"> > <column name="owner_id" primaryKey="true" type="INTEGER" > description="User ID" /> > <column name="friend_id" primaryKey="true" type="INTEGER" > description="User ID" /> > > <foreign-key foreignTable="users"> > <reference local="owner_id" foreign="id"/> > </foreign-key> > <foreign-key foreignTable="users"> > <reference local="friend_id" foreign="id"/> > </foreign-key> > </table> > > <table name="users" description="A Registry User"> > <column name="id" primaryKey="true" type="INTEGER" > description="Unique User ID" /> > <column name="handle" type="VARCHAR" size="32" > description="Unique User Handle"/> > <column name="password" type="VARCHAR" size="255" > description="Unencrypted"/> > <column name="first_name" type="VARCHAR" size="255"/> > <column name="last_name" type="VARCHAR" size="255"/> > </table> > ------------------- > The database after one run (and commenting out the tearDown(): > ------------------ > kim=# select * from users ; > id | handle | password | first_name | last_name > ----+--------+----------+------------+----------- > 26 | one | one | | > 27 | two | two | | > (2 rows) > > kim=# select * from relations ; > owner_id | friend_id > ----------+----------- > (0 rows) > > kim=# \d relations > Table "public.relations" > Column | Type | Modifiers > -----------+---------+----------- > owner_id | integer | not null > friend_id | integer | not null > Indexes: relations_pkey primary key btree (owner_id, friend_id) > Foreign Key constraints: relations_fk_1 FOREIGN KEY (owner_id) > REFERENCES users(id) ON UPDATE NO ACTION ON DELETE NO ACTION, > relations_fk_2 FOREIGN KEY (friend_id) > REFERENCES users(id) ON UPDATE NO ACTION ON DELETE NO ACTION > > kim=# \d users > Table "public.users" > Column | Type | Modifiers > ------------+------------------------+----------- > id | integer | not null > handle | character varying(32) | > password | character varying(255) | > first_name | character varying(255) | > last_name | character varying(255) | > Indexes: users_pkey primary key btree (id) > > kim=# > ---------------------------- > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
