Hibernate Many-To-One Foreign Key Default 0

user573648 picture user573648 · Jan 13, 2011 · Viewed 9.3k times · Source

I have a table where the the parent object has an optional many-to-one relationship. The problem is that the table is setup to default the fkey column to 0.

When selecting, using fetch="join", etc-- the default of 0 on the fkey is being used to try over and over to select from another table for the ID 0. Of course this doesn't exist, but how can I tell Hibernate to treat a value of 0 to be the same as NULL-- to not cycle through 20+ times in fetching a relationship which doesn't exist?

<many-to-one name="device" lazy="false" class="Device" not-null="true" access="field" cascade="none" not-found="ignore">
<column name="DEVICEID" default="0" not-null="false"/>

Answer

Alex Godofsky picture Alex Godofsky · Jan 14, 2011

There are two ways of doing this, the way that can get ugly performance-wise and the way that is painful and awkward.

The potentially ugly way is done on the ToOne end. Using Hibernate Annotations it would be:

@Entity
public class Foo
{
    ...

    @ManyToOne
    @JoinColumn( name = "DEVICEID" )
    @NotFound( action = NotFoundAction.IGNORE )
    private Device device;

    ...
}

Unfortunately, this forces a preemptive database hit (no lazy loading) because device can be null, and if Hibernate created a lazy Device then "device == null" would never be true.

The other way involves creating a custom UserType that intercepts requests for the ID 0 and returns null for them, and then assigning that to the primary key of Device with @Type. This forces the 0 ~ null interpretation on everyone with a foreign key into Device.