Hibernate 3.2.0 has some problems with mapping a foreign key that doesn't reference a primary key.
Scenario:
Table FOO_DATA contains the data for all Foo Objects, which happen to be either
Bar or Baz objects depending on the discriminator.
Overview of the database:
Code:
CREATE TABLE FOO_DATA (
PK_OF_FOO INTEGER NOT NULL PRIMARY KEY,
RELATED_LOCATION_ID INTEGER NOT NULL,
FK_OF_BAZ INTEGER
TYPE VARCHAR(3)
...
)
Many Baz Objects (which have data in FK_OF_BAZ) belong to a Bar Object.
FK_OF_BAZ is a reference to RELATED_LOCATION_ID of a Bar Object. Which would give us following code:
Code:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "FK_OF_BAZ", referencedColumnName = "RELATED_LOCATION_ID")
public Bar getBar() {
return bar;
}
Somehow Hibernate doesn't like this code too much:
- Hibernate doesn't allow us to return a Bar Object.
Hibernate throws an AnnotationException:
referencedColumnNames(RELATED_LOCATION_ID) of Baz.bar referencing Bar not mapped to a single property
We HAVE to return a Foo Object to 'solve' this exception:
Code:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "FK_OF_BAZ", referencedColumnName = "RELATED_LOCATION_ID")
public Foo getBar() {
return bar;
}
- The lazy option seems to have no effect and Foo (which actually is Bar) is always fetched.
I realize that it would be a better design to let FK_OF_BAZ reference to PK_OF_FOO,
but this is not possible at this time due some other database related reasons.
In that case we could have used following code without any problems:
Code:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "FK_OF_BAZ")
public Bar getBar() {
return bar;
}
Overview of the Java classes:Code:
@Entity
@Table(name = "FOO_DATA")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TYPE")
public abstract class Foo {
private Integer id; // primary key
private Integer locationId; // corresponding location id, which is also unique
...
@Id
@Column(name = "PK_OF_FOO")
public Integer getId() {
return id;
}
private void setId(Integer id) {
this.id = id;
}
@Column(name = "RELATED_LOCATION_ID")
public Integer getLocationId() {
return locationId;
}
public void setLocationId(Integer locationId) {
this.locationId= locationId;
}
...
}
Code:
@Entity
@DiscriminatorValue("BAR")
public class Bar extends Foo {
...
}
Code:
@Entity
@DiscriminatorValue("BAZ")
public class Baz extends Foo {
private Bar bar;
...
@ManyToOne(fetch = FetchType.LAZY) // Lazy option has no effect. Hibernate bug?
@JoinColumn(name = "FK_OF_BAZ", referencedColumnName = "RELATED_LOCATION_ID")
public Bar getBar() { // We HAVE to return a Foo Object here. Hibernate bug?
return bar;
}
public void setBar(Bar bar) {
this.bar = bar;
}
}
Is there anybody that can confirm these bugs? Or is there any better way to handle this situation?