Hibernate foreign key as primary key

Discussion in 'Java' started by Lionel, Aug 7, 2011.

  1. Lionel

    Lionel Guest

    This may be a little off topic but I'm sure there are some experts in here.

    I'm having some troubles getting using a foreign key as a primary key.
    In this post I will use the most simple issue I'm having trouble with.

    Here's some snippets (pharmacy project):

    public abstract class AbstractDrugModel
    {
    private String name;
    private IntravascularDrug ivDrug;
    }

    public class IntravascularDrug
    {
    private AbstractDrugModel drug;
    }

    Note 1: I am only just introducing hibernate, previously I did the
    databases manually and in that scenario IntravascularDrug did not
    contain an AbstractDrugModel instance.

    Note 2: ivDrug can be null.

    In my mapping files I have (at this point in time, I've tried other
    approaches):

    <hibernate-mapping>
    <class
    lazy="false"
    name="tciworks.drugmodel.IntravascularDrug"
    table="IntravascularDrug">
    <composite-id>
    <key-many-to-one name="drug" column="DrugName"/>
    </composite-id>
    ...
    </class>
    </hibernate-mapping>

    <hibernate-mapping>
    <class
    dynamic-insert="false"
    dynamic-update="false"
    lazy="false"
    mutable="true"
    name="tciworks.drugmodel.AbstractDrugModel"
    optimistic-lock="version"
    polymorphism="implicit"
    select-before-update="false"
    table="Drug">

    <id column="Name" name="name"/>
    <discriminator column="DrugModelType"/>
    ...
    <many-to-one
    cascade="all"
    column="DrugName"
    name="intravascularDrug"
    not-null="false"
    unique="true"/>

    <subclass
    discriminator-value="USER_DEFINED"
    name="tciworks.drugmodel.userdefined.UserDefinedDrugModel"/>
    </class>
    </hibernate-mapping>

    This example includes only one concrete sub-class of AbstractDrugModel,
    there are others. Drug name is unique hence being used as PK.

    When I have Hibernate create the database tables everything appears
    fine, but on save, it seems to be saving IntravascularDrug first and
    hence gives the following error:

    Sun Aug 07 21:03:25 EST 2011: ERROR logExceptions, Cannot add or update
    a child row: a foreign key constraint fails
    (`tciworkssqlextension`.`intravasculardrug`, CONSTRAINT
    `FK19E96D413937CB47` FOREIGN KEY (`DrugName`) REFERENCES `drug` (`Name`))

    Does anyone have any suggestions on how I should do this?

    Thanks

    Lionel.
     
    Lionel, Aug 7, 2011
    #1
    1. Advertising

  2. Lionel

    markspace Guest

    On 8/7/2011 4:38 AM, Lionel wrote:
    > public abstract class AbstractDrugModel


    > When I have Hibernate create the database tables everything appears
    > fine, but on save, it seems to be saving IntravascularDrug first and
    > hence gives the following error:



    I don't know Hibernate really well, but I'm confused why you think
    Hibernate can persist an abstract class at all. It's abstract. Or do
    you mean that the drug class gets persisted before some other class,
    which you haven't shown?
     
    markspace, Aug 7, 2011
    #2
    1. Advertising

  3. On 07.08.2011 13:38, Lionel wrote:
    > This may be a little off topic but I'm sure there are some experts in here.
    >
    > I'm having some troubles getting using a foreign key as a primary key.
    > In this post I will use the most simple issue I'm having trouble with.
    >
    > Here's some snippets (pharmacy project):
    >
    > public abstract class AbstractDrugModel
    > {
    > private String name;
    > private IntravascularDrug ivDrug;
    > }
    >
    > public class IntravascularDrug
    > {
    > private AbstractDrugModel drug;
    > }
    >
    > Note 1: I am only just introducing hibernate, previously I did the
    > databases manually and in that scenario IntravascularDrug did not
    > contain an AbstractDrugModel instance.
    >
    > Note 2: ivDrug can be null.
    >
    > In my mapping files I have (at this point in time, I've tried other
    > approaches):
    >
    > <hibernate-mapping>
    > <class
    > lazy="false"
    > name="tciworks.drugmodel.IntravascularDrug"
    > table="IntravascularDrug">
    > <composite-id>
    > <key-many-to-one name="drug" column="DrugName"/>
    > </composite-id>
    > ...
    > </class>
    > </hibernate-mapping>
    >
    > <hibernate-mapping>
    > <class
    > dynamic-insert="false"
    > dynamic-update="false"
    > lazy="false"
    > mutable="true"
    > name="tciworks.drugmodel.AbstractDrugModel"
    > optimistic-lock="version"
    > polymorphism="implicit"
    > select-before-update="false"
    > table="Drug">
    >
    > <id column="Name" name="name"/>
    > <discriminator column="DrugModelType"/>
    > ...
    > <many-to-one


    Why "many to one"? Isn't this a "one to one" relationship? At least
    from the looks of your classes it seems to be so.

    > cascade="all"
    > column="DrugName"
    > name="intravascularDrug"
    > not-null="false"
    > unique="true"/>
    >
    > <subclass
    > discriminator-value="USER_DEFINED"
    > name="tciworks.drugmodel.userdefined.UserDefinedDrugModel"/>
    > </class>
    > </hibernate-mapping>
    >
    > This example includes only one concrete sub-class of AbstractDrugModel,
    > there are others. Drug name is unique hence being used as PK.
    >
    > When I have Hibernate create the database tables everything appears
    > fine, but on save, it seems to be saving IntravascularDrug first and
    > hence gives the following error:
    >
    > Sun Aug 07 21:03:25 EST 2011: ERROR logExceptions, Cannot add or update
    > a child row: a foreign key constraint fails
    > (`tciworkssqlextension`.`intravasculardrug`, CONSTRAINT
    > `FK19E96D413937CB47` FOREIGN KEY (`DrugName`) REFERENCES `drug` (`Name`))
    >
    > Does anyone have any suggestions on how I should do this?


    With Oracle you could mark the FK as "deferrable initially deferred"
    which basically means that the constraint is checked at commit time and
    not when updates happen. Maybe your RDBMS supports this feature as well.

    My Hibernate foo is a bit rusty but I think that is the only way to
    solve this with the current class layout because if you have a
    bidirectional one to one relationship one record has to be inserted into
    the database first - which means that the other one isn't there. And if
    the FK field is not allowed to be NULL on both sides then this can never
    work (unless, again, the RDBMS supports deferred constraints).

    I don't know if Hibernate is smart enough to figure insertion order if
    one of the two sides is allowed to be NULL. What do the docs say?

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Aug 7, 2011
    #3
  4. On 07.08.11 13:38, Lionel wrote:
    > This may be a little off topic but I'm sure there are some experts in here.
    >
    > I'm having some troubles getting using a foreign key as a primary key.
    > In this post I will use the most simple issue I'm having trouble with.
    >
    > Here's some snippets (pharmacy project):
    >
    > public abstract class AbstractDrugModel
    > {
    > private String name;
    > private IntravascularDrug ivDrug;
    > }
    >
    > public class IntravascularDrug
    > {
    > private AbstractDrugModel drug;
    > }


    I can't help you with your problem but want to give a comment to this mail.
    Your class design does not make sense to me. You have a circular
    reference between these two classes. Java allows this, but this is bad
    design in my eyes.
    And this might be the cause that hibernate cannot work with this design.
     
    Frank Langelage, Aug 7, 2011
    #4
  5. On 07.08.2011 18:45, Frank Langelage wrote:
    > On 07.08.11 13:38, Lionel wrote:
    >> This may be a little off topic but I'm sure there are some experts in
    >> here.
    >>
    >> I'm having some troubles getting using a foreign key as a primary key.
    >> In this post I will use the most simple issue I'm having trouble with.
    >>
    >> Here's some snippets (pharmacy project):
    >>
    >> public abstract class AbstractDrugModel
    >> {
    >> private String name;
    >> private IntravascularDrug ivDrug;
    >> }
    >>
    >> public class IntravascularDrug
    >> {
    >> private AbstractDrugModel drug;
    >> }

    >
    > I can't help you with your problem but want to give a comment to this mail.
    > Your class design does not make sense to me. You have a circular
    > reference between these two classes. Java allows this, but this is bad
    > design in my eyes.


    .... but very common for bidirectional relationships. If instances of
    both classes need to be able to navigate the relationship that design is
    the most efficient solution.

    > And this might be the cause that hibernate cannot work with this design.


    Yes, might be.

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Aug 7, 2011
    #5
  6. Lionel

    Lionel Guest

    On 08/08/11 03:14, Robert Klemme wrote:
    > On 07.08.2011 18:45, Frank Langelage wrote:
    >> On 07.08.11 13:38, Lionel wrote:
    >>> This may be a little off topic but I'm sure there are some experts in
    >>> here.
    >>>
    >>> I'm having some troubles getting using a foreign key as a primary key.
    >>> In this post I will use the most simple issue I'm having trouble with.
    >>>
    >>> Here's some snippets (pharmacy project):
    >>>
    >>> public abstract class AbstractDrugModel
    >>> {
    >>> private String name;
    >>> private IntravascularDrug ivDrug;
    >>> }
    >>>
    >>> public class IntravascularDrug
    >>> {
    >>> private AbstractDrugModel drug;
    >>> }

    >>
    >> I can't help you with your problem but want to give a comment to this
    >> mail.
    >> Your class design does not make sense to me. You have a circular
    >> reference between these two classes. Java allows this, but this is bad
    >> design in my eyes.

    >
    > ... but very common for bidirectional relationships. If instances of
    > both classes need to be able to navigate the relationship that design is
    > the most efficient solution.


    Yes. This is normal design. But read one.


    >> And this might be the cause that hibernate cannot work with this design.

    >
    > Yes, might be.


    My original relationship was actually unidirectional, there was no need
    for the IntravascularDrug to know about the AbstractDrugModel. However,
    to map the relationship in Hibernate somehow Hibernate needs to be able
    to get the primary key for IntravascularDrug which happens to be the
    primary key of AbstractDrugModel and is hence also a foreign key of
    IntravascularDrug.

    I thought there might be more knowledge of hibernate on this forum, but
    based on the responses it seems it is too specific for this forum. I
    just wasn't getting responses to other questions on the Hibernate forum
    (and neither were many other people though there are a high number of
    posts) so I decided to try on my preferred medium :).

    Thanks everyone for your input.

    Lionel.
     
    Lionel, Aug 8, 2011
    #6
  7. On 11-08-08 07:11 AM, Lionel wrote:
    [ SNIP ]

    > I thought there might be more knowledge of hibernate on this forum, but
    > based on the responses it seems it is too specific for this forum. I
    > just wasn't getting responses to other questions on the Hibernate forum
    > (and neither were many other people though there are a high number of
    > posts) so I decided to try on my preferred medium :).
    >
    > Thanks everyone for your input.
    >
    > Lionel.


    It's one thing if you're not getting Hibernate-specific answers here;
    it's something else entirely if you (and a bunch of other folks) are not
    getting answers on Hibernate forums.

    A suggestion I have is to consider the use of JPA. If you're happy with
    Hibernate keep it as a JPA provider, but stick with the JPA 2
    specification, and use annotations. XML configuration files are better
    than straight text configuration files, by a long shot, but they are in
    turn inferior to annotations; JPA radically cuts down on XML.

    The advantage of sticking with JPA is that it's the overall Java
    persistence specification. You're no longer tied to a specific ORM.
    There's also likely more people and more forums that can answer JPA
    questions...including here. I stopped wasting my time with
    Hibernate/Toplink mapping XML as soon as JPA 1.0 appeared.

    To return to my original point: tepid or no response on
    Hibernate-specific forums. Cause for concern, that.

    AHS
     
    Arved Sandstrom, Aug 8, 2011
    #7
  8. Lionel

    Lionel Guest

    On 09/08/11 07:26, Arved Sandstrom wrote:
    > On 11-08-08 07:11 AM, Lionel wrote:
    > [ SNIP ]
    >
    >> I thought there might be more knowledge of hibernate on this forum, but
    >> based on the responses it seems it is too specific for this forum. I
    >> just wasn't getting responses to other questions on the Hibernate forum
    >> (and neither were many other people though there are a high number of
    >> posts) so I decided to try on my preferred medium :).
    >>
    >> Thanks everyone for your input.
    >>
    >> Lionel.

    >
    > It's one thing if you're not getting Hibernate-specific answers here;
    > it's something else entirely if you (and a bunch of other folks) are not
    > getting answers on Hibernate forums.
    >
    > A suggestion I have is to consider the use of JPA. If you're happy with
    > Hibernate keep it as a JPA provider, but stick with the JPA 2
    > specification, and use annotations. XML configuration files are better
    > than straight text configuration files, by a long shot, but they are in
    > turn inferior to annotations; JPA radically cuts down on XML.
    >
    > The advantage of sticking with JPA is that it's the overall Java
    > persistence specification. You're no longer tied to a specific ORM.
    > There's also likely more people and more forums that can answer JPA
    > questions...including here. I stopped wasting my time with
    > Hibernate/Toplink mapping XML as soon as JPA 1.0 appeared.


    I had wondered about JPA as I was starting with Hibernate. But I'm
    hesitant to back-pedal as this is a project with limited funding.

    I actually prefer the XML mapping approach, the annotations add a lot of
    noise to what can otherwise be a clean model. It may be personal
    preference but I like the separation.

    Does JPA provide the same features as Hibernate? Can you easily
    configure any DBMS? Does it manage objects like Hibernate? Of course I'm
    about to do a little more of my own research right now but I would like
    to hear from someone who has actually used it.

    > To return to my original point: tepid or no response on
    > Hibernate-specific forums. Cause for concern, that.


    Yeah, I'm not sure the exact reason, I will be trying again and paying
    very careful attention to the details of my post to make sure it is
    understandable.

    Thanks

    Lionel.
     
    Lionel, Aug 9, 2011
    #8
  9. On 11-08-09 05:56 AM, Lionel wrote:
    > On 09/08/11 07:26, Arved Sandstrom wrote:
    >> On 11-08-08 07:11 AM, Lionel wrote:
    >> [ SNIP ]
    >>
    >>> I thought there might be more knowledge of hibernate on this forum, but
    >>> based on the responses it seems it is too specific for this forum. I
    >>> just wasn't getting responses to other questions on the Hibernate forum
    >>> (and neither were many other people though there are a high number of
    >>> posts) so I decided to try on my preferred medium :).
    >>>
    >>> Thanks everyone for your input.
    >>>
    >>> Lionel.

    >>
    >> It's one thing if you're not getting Hibernate-specific answers here;
    >> it's something else entirely if you (and a bunch of other folks) are not
    >> getting answers on Hibernate forums.
    >>
    >> A suggestion I have is to consider the use of JPA. If you're happy with
    >> Hibernate keep it as a JPA provider, but stick with the JPA 2
    >> specification, and use annotations. XML configuration files are better
    >> than straight text configuration files, by a long shot, but they are in
    >> turn inferior to annotations; JPA radically cuts down on XML.
    >>
    >> The advantage of sticking with JPA is that it's the overall Java
    >> persistence specification. You're no longer tied to a specific ORM.
    >> There's also likely more people and more forums that can answer JPA
    >> questions...including here. I stopped wasting my time with
    >> Hibernate/Toplink mapping XML as soon as JPA 1.0 appeared.

    >
    > I had wondered about JPA as I was starting with Hibernate. But I'm
    > hesitant to back-pedal as this is a project with limited funding.
    >
    > I actually prefer the XML mapping approach, the annotations add a lot of
    > noise to what can otherwise be a clean model. It may be personal
    > preference but I like the separation.
    >
    > Does JPA provide the same features as Hibernate?


    Well, if you're using Hibernate as the JPA persistence provider then the
    features are identical. :)

    Seriously, though, the entire point of JPA has been to look at what
    various Java ORMs have done, and to arrive at a standard that
    incorporates the important and useful bits. Hibernate has informed the
    JPA process quite a lot; especially with JPA 2 and provider
    customization features I think you'll be hard-pressed to find something
    you need to do that forces you to stray from JPA.

    I haven't used Hibernate in a few years, but I expect that if necessary
    you can do with it, in a JPA environment, what one can do with
    EclipseLink; namely, retrieve references to native implementation
    objects and use those if necessary.

    > Can you easily
    > configure any DBMS?


    Yes. There is a reasonably standard way of doing so in JPA. Ultimately
    as you might expect it still boils down to JDBC connection properties
    and DataSources and what have you.

    > Does it manage objects like Hibernate?


    Yes. There are ORMs and then there are ORMs - some don't go much past
    mapping and others are fully-fledged persistent object managers. JPA is
    intended to support persistent object management, apart from mapping, so
    native persistent object managers in Hibernate and EclipseLink, such as
    sessions/units-of-work, translate fairly directly to the JPA entity manager.

    [ SNIP ]

    AHS
     
    Arved Sandstrom, Aug 10, 2011
    #9
  10. Lionel

    Lew Guest

    On Monday, August 8, 2011 3:11:52 AM UTC-7, Lionel wrote:
    > On 08/08/11 03:14, Robert Klemme wrote:
    > > On 07.08.2011 18:45, Frank Langelage wrote:
    > >> On 07.08.11 13:38, Lionel wrote:
    > >>> This may be a little off topic but I'm sure there are some experts in
    > >>> here.
    > >>>
    > >>> I'm having some troubles getting using a foreign key as a primary key.
    > >>> In this post I will use the most simple issue I'm having trouble with.
    > >>>
    > >>> Here's some snippets (pharmacy project):
    > >>>
    > >>> public abstract class AbstractDrugModel
    > >>> {
    > >>> private String name;
    > >>> private IntravascularDrug ivDrug;
    > >>> }
    > >>>
    > >>> public class IntravascularDrug
    > >>> {
    > >>> private AbstractDrugModel drug;
    > >>> }
    > >>
    > >> I can't help you with your problem but want to give a comment to this
    > >> mail.
    > >> Your class design does not make sense to me. You have a circular
    > >> reference between these two classes. Java allows this, but this is bad
    > >> design in my eyes.

    > >
    > > ... but very common for bidirectional relationships. If instances of
    > > both classes need to be able to navigate the relationship that design is
    > > the most efficient solution.

    >
    > Yes. This is normal design. But read one.
    >
    >
    > >> And this might be the cause that hibernate cannot work with this design.

    > >
    > > Yes, might be.

    >
    > My original relationship was actually unidirectional, there was no need
    > for the IntravascularDrug to know about the AbstractDrugModel. However,
    > to map the relationship in Hibernate somehow Hibernate needs to be able
    > to get the primary key for IntravascularDrug which happens to be the
    > primary key of AbstractDrugModel and is hence also a foreign key of
    > IntravascularDrug.
    >
    > I thought there might be more knowledge of hibernate [sic] on this forum, but
    > based on the responses it seems it is too specific for this forum. I
    > just wasn't getting responses to other questions on the Hibernate forum
    > (and neither were many other people though there are a high number of
    > posts) so I decided to try on my preferred medium :).


    The annotative version (JPA-compliant) would be easier to follow.

    --
    Lew
     
    Lew, Aug 10, 2011
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. shaji
    Replies:
    3
    Views:
    24,602
    shaji
    Aug 30, 2005
  2. H5N1
    Replies:
    0
    Views:
    442
  3. Harry George
    Replies:
    9
    Views:
    705
    sonal
    Jun 13, 2006
  4. Wolfgang Keller
    Replies:
    5
    Views:
    487
    Wolfgang Keller
    Nov 9, 2007
  5. snehasish
    Replies:
    0
    Views:
    1,630
    snehasish
    Oct 27, 2009
Loading...

Share This Page