-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Bidirectional X-to-one on primary key (with annotations)
PostPosted: Wed Apr 14, 2010 9:32 am 
Newbie

Joined: Wed Apr 14, 2010 9:07 am
Posts: 3
Hi all,

I am having some problems designing the model to represent an existing legacy database schema. I've been referring to the documentation, and while it has lots of individual bits of information that are relevant and helpful I can't figure out how to combine them into the overall picture of what I need. The schema is broadly hierarchical, and each entity has a (potentially) composite primary key, consisting of the "parent" ID and any unique identifiers for the entity itself.

Even at the top level however I am running into problems. The schema for the section I am interested in looks like this:
Code:
ROOT_ENTITY           fkey        ENTITY_ACCESS_DETAILS
entity_pkey      <----------->    entity_pkey
*other non-key columns*           *other non-key columns*
    /\
   /  \
  /    \
other child tables


The way the model will be used in the code (and additionally how it conceptually works), I need a link from the RootEntity to the EntityAccessDetails. However, since the AccessDetails doesn't have its own pkey but inherits the key of the Root, we need the relationship mapped in that direction as well.

I have not yet been able to come up with a model that works for both persistence and querying. The closest I have come so far is the following:
Code:
@Entity
@Table(name = "ROOT_ENTITY")
public class RootEntity {
    @Id @GeneratedValue(/*generated by sequence, details removed*/)
    Integer entity_pkey;

    @OneToOne
    @PrimaryKeyJoinColumn
    AccessDetails accessDetails;

    // Other bits
}

--

@Entity
@Table(name = "ENTITY_ACCESS_DETAILS")
public class AccessDetails {
    @EmbeddedId
    ADKey pkey;

    // Other bits
}

@Embeddable
class ADKey implements Serializable {
    @OneToOne
    @JoinColumn("entity_pkey")
    RootEntity entity;
}

This works great during persistence; I can create a RootEntity, then create an associate an AccessDetails object, and when I call save() on the RootEntity both tables are populated correctly (both with the same autogenerated ID). However, when I load the root entity with a query ("from RootEntity e where e.active='Y' and e.entityName=?"), the access details field is always null (not even a proxy). If I force non-lazy loading ("from RootEntity e left join fetch e.accessDetails where e.active='Y' and e.entityName=?"), then a StackOverflowException is the result.

I understood from this last outcome that both entities are trying to load each other, and that I need to make one side the "owner" of the relationship. This would need to be the RootEntity, as that's the class that's generating the ID and propagating it out to the other classes. However, if I modify my ADKey class' annotation to read @OneToOne(mappedBy = "accessDetails"), the session factory will not even load: "org.hibernate.AnnotationException: com.package.ADKey has no persistent id property".

At this point I give up trying to work things out solely through following the documentation (which, by the way, I have been). It seems like my situation is not that outrageous; what would be the canonical way to map it and make both persistence and loading work?

Many thanks in advance.


Top
 Profile  
 
 Post subject: Re: Bidirectional X-to-one on primary key (with annotations)
PostPosted: Wed Apr 14, 2010 9:54 am 
Newbie

Joined: Wed Apr 14, 2010 9:07 am
Posts: 3
In fact, after thinking about this a little more perhaps my assertion that bidirectionality is required was a little too strong. I don't actually care that the AccessDetails class has a link to RootEntity; rather, I do care that the ID of the AccessDetails class is generated to be the same as then enclosing RootEntity.

So in principle, we could have a standard unidirectional link, the AccessDetails could just have an integer ID and this could be populated by an appropriate generator. In practice, I suspect the reverse link may be needed (so that we know what the "enclosing RootEntity" actually is in order to resolve its ID).

It seems like the root cause might be that Hibernate doesn't like a class having an ID composed solely of a @OneToOne? This would of course be the most intuitive way to map the AccessDetails class (instead of using an embedded ID), but I ran into a variety of problems while trying to map this one way or another.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.