So far I like what I found in GLORP.Having built a ORM solution in the past (still being used successfully), I still have a few questions about what is the proper way to use GLORP.1) Should I create a new GlorpSession everytime I want to read/save/update an object?It is... is a GlorpSession "a window" to the objects persisted in the database.
2) I know some objects can live outside of a UnitOfWork (UOW), but how do they behave when used inside a UOW.
3) If a UnitOfWork fails, does the session remain usable? or should I throw it away?
I'm going to use GLORP in the context of a Seaside application (where I can have one glorp session per seaside session) and also independently by means of a globally accessible (i.e. singleton) system object.
4) Can I use the same login object for different database accessors?
5) Can the 31 table name limit be lifted? I know this has to with ORACLE (everybody hates Oracle), but I'm using PostgreSQL, and won't change it for anything else other than something more modern (which is unlikely).
6) Can I map a class name to a column, and an ID to other, and use those two to instantiate an object?In the ORM I made, you have a special mapping that works together with other kind of mapping, that when combined allow you to have a reference to ANY object.I.e., you can have N:M relationships stored in a single table.The tuple would be something like PARENT_CLASS, PARENT_ID, CHILD_CLASS, CHILD_ID.Of course this can't use the underlying database referential integrity. But after several years using it, it hasn't presented any issues.
Does exist "the good GLORP user guide" somewhere? :-)
So far I like what I see.Regards,--Esteban.
--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to glorp-group...@googlegroups.com.
To post to this group, send email to glorp...@googlegroups.com.
Visit this group at http://groups.google.com/group/glorp-group.
For more options, visit https://groups.google.com/groups/opt_out.
--
You received this message because you are subscribed to a topic in the Google Groups "glorp-group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/glorp-group/pNw3fpPE1wk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to glorp-group...@googlegroups.com.
Hi Alan, Tom,First of all, thanks for your responses.I'm developing a system that is not going to be "high demand" but will have around 50 concurrent users. With peaks of REAL concurrence of 20 or so users. Coming through a REST API from a mobile application.As for the Seaside users, they're going to be a few (around 10) doing backoffice tasks and administration.I have trouble understanding how the interaction between objects read "outside" of a UOW behave with objects read within a UOW, and if such interaction is recommendable.Seems to me that a UOW is:+ a in-memory transaction+ a database interaction (insert/update/delete) if it finishes ok based on the object "touched" during the UOW(how is this detected I don't know)
New set of questions:1) let's suppose I have aCustomer, read in aSession outside of a UOW. So it is "detached" (is this the proper word?) from the UOW.But the user have some "ToMany" relations, i.e. #orders.Is it ok to add or remove orders to such customers inside of a a UOW?E.g.| customer |customer := session read: Customer where: [:each | each name = 'Customer 1'].session inUnitOfWorkDo: [| order |order := Order forCustomer: customer.3 timesRepeat: [order addSampleItem].customer addOrder: order.].1.a) Is this a good practice?
1.b) Will the order and its items be saved in the database automatically?
2) So, to not be "too detached from reality" (the DB) the session cache should be flushed regularly, otherwise the in-memory cache would diverge from what's in the database and cause conflicts.
3) If I want to be as close as possible to what's in the DB (paying the IO+instantiation penalty) I should work inside a UOW and flush the session cache at the end of each unit of work.
4) Does the framework come with some sort of session/connection pooling?I'm using the Pharo / OpenDBX version of it.
5) How can I get rid of the 31 characters limit of constraints/table names, etc?I'm already working with my own subclass of PostgresSQLPlatform
Esteban A. Maringolo
Okay, so I should only use UOW if I want to be able to rollback a
2013/9/26 Alan Knight <kni...@acm.org>
> A UOW is really just the in-memory transaction. However, if you're not already inside a database transaction, then at the end of the UOW it will begin a transaction, write the objects, then commit. If you're already inside a transaction, then it will just write the objets.
>
> It detects if the objects are touched by comparing their current state against the state they had when they were registered with the unit of work. We don't have a portable write barrier across all Smalltalks, so we rely on the user telling us. If you're in VisualWorks there is a write barrier you can use hooked up to Glorp.
change made in memory. But if I already have other method (like
mementos, buffered copies, etc.) to rollback or verify changes before
storing it in the database then I could avoid the use of UOW for
normal things like saving a new customer or adding an order to it (or
simply saving the order).
Perfectly clear. Couldn't the write barrier be implemented by means of
> So the important interaction is that if an object was read outside of a UOW, then we don't know anything about its state, and the user has to tell us that this object might get modified.
immutability? We did that in Dolphin...
>> 1.b) Will the order and its items be saved in the database automatically?But if I read the object inside the UOW then it will.
> No.
So for a REST API, I should implement a pool of sessions (which in
>> 2) So, to not be "too detached from reality" (the DB) the session cache should be flushed regularly, otherwise the in-memory cache would diverge from what's in the database and cause conflicts.
> That's one strategy. There is an optimistic locking mechanism available to find conflicts, but you still might be presenting the user with stale data. You can also refresh individual objects or groups of objects to ensure they're consistent while still retaining object identity. But for REST users, it might be quite reasonable to just empty the cache between every REST request, or to empty it except for very rarely-changing objects that are always used.
turn could share a pool of connections), and perform a cycle of
aquire, use, flush and release on every HTTP request.
Isn't the transaction just a "wrapper" to the underlying DB transaction?
>> 3) If I want to be as close as possible to what's in the DB (paying the IO+instantiation penalty) I should work inside a UOW and flush the session cache at the end of each unit of work.
> Yes. Or work inside a transaction.
It is... transaction cycle is:
1. Begin DB Transaction
2. Begin UOW
3. Execute transaction block
4. Commit UOW
5. Commit DB Transaction
Is this correct?
Or does the transaction does something related with the session cache?
The REST sessions are 100% stateless, so a pool like the mentioned
>> 4) Does the framework come with some sort of session/connection pooling?
>> I'm using the Pharo / OpenDBX version of it.
> There is a basic mechanism for connection pooling at the Glorp level in VisualWorks, I don't know if it was ported. It often works better if you can exploit a database-level mechanism for that. But for REST interactions you might reasonably just maintain your own pool of active sessions, which should be very simple.
above should do the job.
I'm seeing it ForeignKeyConstraint>>#generateName, it referes to the
>> 5) How can I get rid of the 31 characters limit of constraints/table names, etc?
>> I'm already working with my own subclass of PostgresSQLPlatform
> Where are you seeing it? I don't know why that should be affecting Postgres. I'd say either try stepping through table creation and see where it's happening, or look for methods with words like maximum and length on their name in the platform hierarchy.
Platform #maximumLengthOfTableName, which in PostgreSQLPlatform is set
to 31.
I just tested creating a 60+ FK name and it worked okey in PG 9.3.
As a side not, can I specify a "ON DELETE CASCADE" in the foreign key
definition?
Thanks for your prompt responses.
Regards,