All,

Again -- many thanks to the posters and responders on this thread. i've
moved on to attempt to use
ScalaQuery<http://github.com/szeiger/scala-query/tree/master>as the
target for the SQL persistence. Stefan Szeiger describes his work
here<http://szeiger.de/blog/2008/12/21/a-type-safe-database-query-dsl-for-scala/#more-24>
.

It seems to be a week of meeting resistance, however. i've been attempting
to build the simplest possible collection to use as a toy to test my
compilation strategy. This has turned out to be quite a little brain-teaser.

For me simpler means: contains less information. In this sense, a Set is
simpler than a List. The simplest possible collection i can imagine (that
still supports associativity -- and i don't know if i can call something
that doesn't support associativity a collection) is a monad. A monad doesn't
commit to what the collection contains; only parametrically commits to how
to put things into the collection; and only parametrically commits to how to
flatten the collection (which is tantamount to supporting associativity).

After thinking about it for half a day, and revisiting the
Moors-Piessens-Odersky (MPO) paper on higher-kinded types, i realized that
the MPO construction doesn't actually apply to Scala in practice (someone
please tell me if i'm wrong) because they fundamentally rely on
constructions using type *members* and not type *parameters*. Unfortunately,
most of the collections libraries are written using type parameters. So, i
decided to roll my own and see what i got.

Here's what i came up with last night.

// smallest expression of monad i can find
trait MBrace[C[_] <: MBrace[C,A],A] {
  def nest( a : A ) : C[A]
  def flatten[T <: C[C[A]]]( bsq : T ) : C[A]
}

// one of the simplest witnesses of monad i can find
class MBraceSeq[A]( a_ : A* ) extends Seq[A] with MBrace[MBraceSeq,A] {
  override def nest( a : A ) = new MBraceSeq[A]( a )
  override def flatten[T <: MBraceSeq[MBraceSeq[A]]]( bsq : T ) :
MBraceSeq[A] = {
    (new MBraceSeq[A]( ) /: bsq)( {
      ( acc : MBraceSeq[A], e : MBraceSeq[A] ) => ( acc ++ e
).asInstanceOf[MBraceSeq[A]]
    } )
  }
  override def length = a_.length
  override def elements = a_.elements
  override def apply( n : Int ) = a_.apply( n )
}

i was mostly ok with this -- apart from some desiderata/concerns regarding
the Seq methods being visible at this level. i woke up this am and realized
that this is not even wrong. It requires an instance of MBrace to invoke the
nest or flatten methods.

Geez, i feel like a first year undergrad. All i want to do is write the
simplest possible collection on which i can then test a persistence
strategry and i run into roadblocks everywhere. ;-)

Best wishes,

--greg

On Wed, Jun 24, 2009 at 8:00 AM, Derek Chen-Becker <dchenbec...@gmail.com>wrote:

> Well, in my real-world experience I've never had very complex models and
> I've never used TABLE-PER-CLASS either, so I don't really have a feel for
> what's not possible. Generally I think that JPA (which is a subset of
> Hibernate) covers a good portion of people's needs for ORM, but it
> definitely has some big missing functionality (e.g. no ordered collections
> until JPA 2). I think that in this case Greg is pushing the limits on a
> relatively unused corner of JPA (I've never seen someone use TABLE-PER-CLASS
> before) and he's hitting some bugs. I want to make clear that I think that
> what Greg is attempting is entirely possible. My earlier comment about
> rolling your own ORM was because I misunderstood what he was doing with
> abstract classes. In my mind, there would be a couple of places where you
> might want to roll your own stuff:
>
>
>    1. An existing schema that doesn't map well to an object graph. We have
>    a legacy database at work where the brilliant developers decided that
>    nothing should be normalized and data can exist in one of four tables based
>    on some arcane business logic. You can still build an ORM layer on 
> something
>    like this, but essentially all you're doing is creating a thin wrapper on
>    ResultSets
>    2. You have very specific data that you need to retrieve with possibly
>    complex joins, and you need it to be as performant as possible. There are
>    some tricks you can do with EJB QL to make it prefetch things, but often 
> you
>    can end up with multiple round trips to the database and/or data that you
>    don't need being fetched. In certain scenarios I could see this being an
>    issue.
>
> This list isn't intended to be exhaustive, these are just the top two that
> come to mind. In terms of Hibernate vs others like JPOX, TopLink, etc, I'd
> say that Hibernate is a first-class provider and at least equal to the
> others.
>
> Derek
>
>
> On Wed, Jun 24, 2009 at 2:21 AM, TSP <tim.pig...@optrak.co.uk> wrote:
>
>>
>> Derek
>> Would you distinguish between what is achievable in a specific ORM
>> such as Hibernate from JPA in this statement or would you think it
>> applies to all. I've got to "go with hibernate" in any case because of
>> widespread use of UserTypes. Unlike Greg, in my case I can hand-craft
>> all my hibernate xml files if I need.
>>
>> Tim
>>
>> On Jun 23, 1:46 am, Derek Chen-Becker <dchenbec...@gmail.com> wrote:
>> > For sufficiently complex relationships, JPA is not a good fit. Beyond a
>> > certain point it's usually simpler to roll your own. I think that this
>> is
>> > somewhat of a failing of the model, but it's not a simple problem to
>> solve
>> > in the generic case.
>> >
>> > Derek
>> >
>> > On Mon, Jun 22, 2009 at 6:45 PM, Derek Chen-Becker <
>> dchenbec...@gmail.com>wrote:
>> >
>> >
>> >
>> > > Ah, sorry, I lost track of the thread.
>> >
>> > > On Mon, Jun 22, 2009 at 4:55 PM, Meredith Gregory <
>> > > lgreg.mered...@gmail.com> wrote:
>> >
>> > >> Derek,
>> >
>> > >> You are correct and i noted and reported this on Scala on Friday.
>> However,
>> > >> if you have a chain of the form
>> >
>> > >> AbstractClass <- Class <-contains- AbstractClass <-Class <-contains-
>> ...
>> >
>> > >> The @MappedSuperclass solution fails at level 2.
>> >
>> > >> Best wishes,
>> >
>> > >> --greg
>> >
>> > >> On Mon, Jun 22, 2009 at 3:52 PM, Derek Chen-Becker <
>> dchenbec...@gmail.com
>> > >> > wrote:
>> >
>> > >>> Something I just want to throw out into the discussion: Since you're
>> > >>> using table-per-class, having a @Table annotation on
>> AbstractContainer
>> > >>> doesn't do anything since abstract classes can't have instances.
>> Tables are
>> > >>> only generated for abstract classes if you're using a JOINED
>> inheritance
>> > >>> strategy. You might want to look at using the MappedSuperclass
>> annotation
>> > >>> for the abstract base class instead. If I change the
>> AbstractContainer def
>> > >>> to:
>> >
>> > >>> @MappedSuperclass
>> > >>> public abstract class AbstractContainer implements
>> java.io.Serializable {
>> >
>> > >>> and then modify MySampleFuContainer to:
>> >
>> > >>> public class MySampleFuContainer extends AbstractContainer {
>> >
>> > >>> then I seem to get the proper schema:
>> >
>> > >>>     create table lingo_production.MySampleFuContainer_table (
>> > >>>         id varchar(255) not null,
>> > >>>         uuid varchar(255),
>> > >>>         mysamplingmumble__idSuper varchar(255),
>> > >>>         primary key (id),
>> > >>>         unique (uuid)
>> > >>>     );
>> >
>> > >>> Having said that, I think that the behavior you're currently seeing
>> > >>> appears to be a bug.
>> >
>> > >>> Derek
>> >
>> > >>> On Mon, Jun 22, 2009 at 3:43 PM, Meredith Gregory <
>> > >>> lgreg.mered...@gmail.com> wrote:
>> >
>> > >>>> Kris,
>> >
>> > >>>> Here<
>> http://svn.biosimilarity.com/src/open/codesamples/trunk/hibernate/>is a
>> link to the self-contained example that now uses just Java. i included
>> > >>>> the target dir in the repo to speed up investigation, but you can
>> just blow
>> > >>>> that away and build from scratch. The example is currently written
>> to
>> > >>>> Java1.6, but also exhibits the same behavior under Java1.5. To run
>> the
>> > >>>> example
>> >
>> > >>>> > svn co
>> > >>>>http://svn.biosimilarity.com/src/open/codesamples/trunk/hibernate
>> > >>>> ...
>> > >>>> > env PATH=<path-to-java1.6>:$PATH JAVA_HOME=<path-to-java1.6> mvn
>> clean
>> > >>>> compile process-classes
>> >
>> > >>>> If you switch comment and decl at line 22 in
>> > >>>> src/main/java/maxb/hbex2/MySampleFuContainer.java then you see the
>> error.
>> > >>>> The schema goes from
>> >
>> > >>>> create table lingo_production.MySampleFuContainer_table (
>> > >>>>         id_AbstractContainer varchar(255) not null,
>> > >>>>         varchar(255) not null,
>> > >>>>         uuid varchar(255),
>> > >>>>         mysamplingmumble__idSuper varchar(255),
>> > >>>>         primary key (id),
>> > >>>>         unique (uuid)
>> > >>>>     );
>> >
>> > >>>> to
>> >
>> > >>>> create table lingo_production.MySampleFuContainer_table (
>> > >>>>         id_AbstractContainer varchar(255) not null,
>> > >>>>         id varchar(255),
>> > >>>>         mysamplingmumble_ tinyblob,
>> > >>>>         uuid varchar(255),
>> > >>>>         primary key (id_AbstractContainer),
>> > >>>>         unique (id_AbstractContainer)
>> > >>>>     );
>> >
>> > >>>> Best wishes,
>> >
>> > >>>> --greg
>> >
>> > >>>> On Mon, Jun 22, 2009 at 1:38 PM, Meredith Gregory <
>> > >>>> lgreg.mered...@gmail.com> wrote:
>> >
>> > >>>>> Kris,
>> >
>> > >>>>> Thanks for the suggestion. i've now got a tiny little example that
>> > >>>>> compiles on its own that illustrates the problem. Changing the
>> inheritance
>> > >>>>> strategy to JOINED makes no difference. Hibernate still does the
>> wrong
>> > >>>>> thing.
>> >
>> > >>>>> Best wishes,
>> >
>> > >>>>> --greg
>> >
>> > >>>>> On Mon, Jun 22, 2009 at 8:55 AM, Kris Nuttycombe <
>> > >>>>> kris.nuttyco...@gmail.com> wrote:
>> >
>> > >>>>>> This may be off the mark, but I'm wondering if the reason that
>> you're
>> > >>>>>> having difficulty with the parallel inheritance hierarchy problem
>> is
>> > >>>>>> not your use of TABLE_PER_CLASS inheritance. In my application, I
>> have
>> > >>>>>> a similar construct, but I am using JOINED_TABLE inheritance.
>> This
>> > >>>>>> allows for a normal foreign key relationship to be created in the
>> > >>>>>> database between C2_table and the base table for CThing, with the
>> > >>>>>> result that Hibernate will generate the query for CThing member
>> as a
>> > >>>>>> union. Using table per class inheritance, I would expect
>> Hibernate to
>> > >>>>>> need to synthesize an additional dtype field in C2_table along
>> with
>> > >>>>>> the key column in order to enforce the uniqueness of the keys to
>> the
>> > >>>>>> joined entities, and I don't believe that it does this.
>> >
>> > >>>>>> I'm not sure how the fact that the code is generated is
>> particularly
>> > >>>>>> relevant; surely if it's possible to hand-write a successful
>> solution,
>> > >>>>>> then your code generator could be made aware of how to construct
>> a
>> > >>>>>> viable solution?
>> >
>> > >>>>>> Kris
>> >
>> > >>>>>> On Fri, Jun 19, 2009 at 8:47 PM, Meredith
>> > >>>>>> Gregory<lgreg.mered...@gmail.com> wrote:
>> > >>>>>> > All,
>> >
>> > >>>>>> > i had a similar problem and found the source of the issues.
>> Spse you
>> > >>>>>> have a
>> > >>>>>> > container hierarchy (CTop <- C2) side-by-side with a contained
>> > >>>>>> hierarchy
>> > >>>>>> > (CThing <- CThing1). The inheritance at the top of the
>> container
>> > >>>>>> hierarchy,
>> > >>>>>> > CTop, causes hibernate to bail on tracking the relations and
>> punt to
>> > >>>>>> > embedded values instead. Rewriting the top to be a
>> @MappedSuperClass
>> > >>>>>> fixes
>> > >>>>>> > the problem in this specific case. However, if your hierarchy
>> is
>> > >>>>>> deep,
>> > >>>>>> > you're screwed.
>> >
>> > >>>>>> > If anybody has a suggestion for a workaround, i'm all ears. The
>> > >>>>>> problem is
>> > >>>>>> > that it would appear that both Mr Crowley and i are generating
>> Java
>> > >>>>>> + JPA
>> > >>>>>> > code. So, the solution needs to be algorithmic and not 1-off.
>> >
>> > >>>>>> > Perhaps the best solution is to find an alternative to
>> hibernate as
>> > >>>>>> this is
>> > >>>>>> > a particularly irritating bug.
>> >
>> > >>>>>> > Best wishes,
>> >
>> > >>>>>> > --greg
>> >
>> > >>>>>> > @Entity
>> > >>>>>> > @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
>> > >>>>>> > abstract class CTop {
>> > >>>>>> >    ...
>> > >>>>>> >    @Id
>> > >>>>>> >     @GeneratedValue(generator = "system-uuid")
>> > >>>>>> >     @GenericGenerator(name = "system-uuid", strategy = "uuid")
>> > >>>>>> >     private String id_CTop;
>> > >>>>>> > }
>> >
>> > >>>>>> > @Entity
>> > >>>>>> > @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
>> > >>>>>> > abstract class CThing {
>> > >>>>>> >    ...
>> > >>>>>> >    @Id
>> > >>>>>> >     @GeneratedValue(generator = "system-uuid")
>> > >>>>>> >     @GenericGenerator(name = "system-uuid", strategy = "uuid")
>> > >>>>>> >     private String id_CThing;
>> > >>>>>> > }
>> >
>> > >>>>>> > @Entity
>> > >>>>>> > @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
>> > >>>>>> > @Table(name = "C2_table", catalog = "mydb_production",
>> > >>>>>> uniqueConstraints = {
>> > >>>>>> > @UniqueConstraint(columnNames = "uuid") })
>> > >>>>>> > class C2 extends CTop {
>> > >>>>>> >    CThing thing;
>> > >>>>>> > ...
>> > >>>>>> >   @OneToOne
>> > >>>>>> >     @JoinColumn
>> > >>>>>> >     public CThing getThing() {
>> > >>>>>> >         return this.thing;
>> > >>>>>> >     }
>> > >>>>>> >     public void setThing( CThing thing ) {
>> > >>>>>> >         this.thing = thing;
>> > >>>>>> >     }
>> >
>> > >>>>>> > @Column(name = "uuid", unique = false, nullable = true,
>> insertable =
>> > >>>>>> true,
>> > >>>>>> > updatable = true)
>> > >>>>>> >     public String getUuid() {
>> > >>>>>> >         return this.uuid;
>> > >>>>>> >     }
>> >
>> > >>>>>> >     public void setUuid(String uuid) {
>> > >>>>>> >         this.uuid = uuid;
>> > >>>>>> >     }
>> >
>> > >>>>>> >     @Id
>> > >>>>>> >     @GeneratedValue(generator = "system-uuid")
>> > >>>>>> >     @GenericGenerator(name = "system-uuid", strategy = "uuid")
>> > >>>>>> >     @Column(name = "id", unique = false, nullable = true,
>> insertable
>> > >>>>>> = true,
>> > >>>>>> > updatable = true)
>> > >>>>>> >     public String getId() {
>> > >>>>>> >         return this.id;
>> > >>>>>> >     }
>> >
>> > >>>>>> > }
>> >
>> > >>>>>> > @Entity
>> > >>>>>> > @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
>> > >>>>>> > @Table(name = "CThing1_table", catalog = "mydb_production",
>> > >>>>>> > uniqueConstraints = { @UniqueConstraint(columnNames = "uuid")
>> })
>> > >>>>>> > class CThing1 extends CThing {
>> > >>>>>> > ...
>> > >>>>>> >   // lots of ground type fields
>> >
>> > >>>>>> > @Column(name = "uuid", unique = false, nullable = true,
>> insertable =
>> > >>>>>> true,
>> > >>>>>> > updatable = true)
>> > >>>>>> >     public String getUuid() {
>> > >>>>>> >         return this.uuid;
>> > >>>>>> >     }
>> >
>> > >>>>>> >     public void setUuid(String uuid) {
>> > >>>>>> >         this.uuid = uuid;
>> > >>>>>> >     }
>> >
>> > >>>>>> >     @Id
>> > >>>>>> >     @GeneratedValue(generator = "system-uuid")
>> > >>>>>> >     @GenericGenerator(name = "system-uuid", strategy = "uuid")
>> > >>>>>> >     @Column(name = "id", unique = false, nullable = true,
>> insertable
>> > >>>>>> = true,
>> > >>>>>> > updatable = true)
>> > >>>>>> >     public String getId() {
>> > >>>>>> >         return this.id;
>> > >>>>>> >     }
>> >
>> > >>>>>> > }
>> >
>> > >>>>>> > On Tue, Jun 16, 2009 at 1:45 PM, Derek Chen-Becker <
>> > >>>>>> j...@chen-becker.org>
>> > >>>>>> > wrote:
>> >
>> > >>>>>> >> John Nilsson wrote:
>> > >>>>>> >> > Hi,
>> >
>> > >>>>>> >> > I think the showSql property has been deprecated in favor of
>> > >>>>>> log4j
>> > >>>>>> >> > loggers.
>> >
>> > >>>>>> >> > If you set the log4j level to TRACE for org.hibernate you'll
>> get
>> > >>>>>> >> > everything Hibernate has to say about what
>> >
>> > ...
>> >
>> > read more ยป
>>
>>
>
> >
>


-- 
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117

+1 206.650.3740

http://biosimilarity.blogspot.com

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to