« Return to Thread: [scala] JPA question

Re: [Lift] Re: [scala] JPA question

by Meredith Gregory :: Rate this Message:

Reply to Author | View in Thread

Derek,

i completely concur. i wanted to give it a serious go, however, before i abandoned it. The issue is that so much of the incumbent technology goes across this object-relational boundary, i needed a simple case to justify walking away from this technology. This example provides it. To see just how non-complex it is, let me state it in common sense terms.
  1. Suppose we are building an app for a manufacturing firm, and the firm ships out its goods in different kinds of containers: plastic-coated cardboard boxes, metal boxes, etc.
  2. Suppose that different kinds of materials go into different kinds of boxes, and sometimes medicinal or toxic substances go into these containers; but, every container gets a manifest. When the container contains these materials that need to be handled with care or attention, the manifest is a special kind of certified manifest.
We might imagine that this firm has already constructed an object model that looks like

abstract class Container { ...; Manifest getManifest(); void setManifest( Manifest manifest ); ... }
class CardboardContainer extends Container { ... }
class MetalContainer extends Container { ... }
abstract class Manifest { ... }
class StdManifest extends Manifest { ... }
class CertifiedManifest extends Manifest { ... }

We need to work with their existing infrastructure. However, this situation/model breaks Hibernate's implementation of JPA. That such a simple situation would cause problems indicates to me that these technologies have never been used in any significant way in production -- otherwise they would have bumped into such a common case. If i'm wrong about something, here, i'd love to be disabused of my misunderstanding(s). Currently, i feel i have enough justification to go to a different kind of solution, such as a LINQ-based solution.

Best wishes,

--greg

On Mon, Jun 22, 2009 at 5:46 PM, Derek Chen-Becker <dchenbecker@...> 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 <dchenbecker@...> wrote:
Ah, sorry, I lost track of the thread.


On Mon, Jun 22, 2009 at 4:55 PM, Meredith Gregory <lgreg.meredith@...> 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 <dchenbecker@...> 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.meredith@...> wrote:
Kris,

Here 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.meredith@...> 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.nuttycombe@...> 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.meredith@...> 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 <java@...>
> 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 it is doing. Can't remember
>> > which one it is, but I know one of the loggers will give you the
>> > values used in queries at the TRACE level.
>>
>> Good to know. Thanks!
>>
>
>
>
> --
> L.G. Meredith
> Managing Partner
> Biosimilarity LLC
> 1219 NW 83rd St
> Seattle, WA 98117
>
> +1 206.650.3740
>
> http://biosimilarity.blogspot.com
>



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

+1 206.650.3740

http://biosimilarity.blogspot.com



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

+1 206.650.3740

http://biosimilarity.blogspot.com








--
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@...
To unsubscribe from this group, send email to liftweb%2Bunsubscribe@...
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---




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

+1 206.650.3740

http://biosimilarity.blogspot.com

 « Return to Thread: [scala] JPA question