Hibernate foreign key as primary key


L

Lionel

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.
 
Ad

Advertisements

M

markspace

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?
 
R

Robert Klemme

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
 
F

Frank Langelage

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.
 
R

Robert Klemme

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
 
L

Lionel

... 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.

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.
 
Ad

Advertisements

A

Arved Sandstrom

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
 
L

Lionel

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.
 
A

Arved Sandstrom

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
 
Ad

Advertisements

L

Lew

... 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.

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top