Hi *,
after a couple of days searching for a solution to my problem I'm finally going to bother you with that issue.
The project uses a mapping files as well as annotations. The annotations pertain a single class hierarchy.
The root looks like this
Code:
@Entity(name = "rootentity")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class RootEntity implements SomeInterface {
...
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long serialId = null;
@OneToMany(cascade = { CascadeType.ALL }, targetEntity = EntityProp.class)
@JoinColumn(name = "rootentity_id", referencedColumnName="id")
@MapKey(name = "name")
@LazyCollection(LazyCollectionOption.EXTRA)
private Map<String, EntityProp<?>> properties = new Hashtable<String, EntityProp<?>>();
@OneToMany(cascade = { CascadeType.ALL }, targetEntity = Representer.class)
@JoinColumn(name = "rootentity_id", referencedColumnName="id")
@LazyCollection(LazyCollectionOption.EXTRA)
private Set<Representer> representations = new HashSet<Representer>();
@ManyToOne(targetEntity = Container.class)
@JoinColumn(name = "container_id", referencedColumnName="id")
@ForeignKey(name="FK_RootEntity_Container")
protected Container container;
...
}
The implemented interface is not relevant for persistence issues. Just giving the details in case it could be relevant.
The RootEntity is extended by five abstract children all having own fields but are annotated the same way
Code:
@Entity(name = "entitya")
@SecondaryTable(name = "entitya")
@ForeignKey(name = "FK_EntityA_RootEntity")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula(<SQL making own type field the discriminator>)
public abstract class EntityA extends RootEntity {
// own fields
}
The concrete extension classes for these children map like follows:
Code:
@Entity
@Table(name = "entitya")
public class SubEntityA extends EntityA {
// no own fields -> no additional table columns
}
Though, I don't think the Container plays a role in the issue I'll post it, too. It is covered by a mapping file, here's a possibly relevant excerpt:
Code:
<class name="Container" table="container">
<!-- own field mappings -->
<!-- Collection of EntityAs -->
<set name="entityas" inverse="true"
cascade="save-update, delete, delete-orphan" lazy="extra">
<key column="container_id" unique="false"
foreign-key="FK_Container_EntityA" not-null="false" />
<one-to-many class="EntityA" not-found="ignore" />
</set>
<!-- Collection of other entities extending RootEntity -->
</class>
So, the problem itself:
Anytime I create the schema for the (MySQL 5.0, InnoDB) database I end up with three foreign keys for each joined sub-class.
One, referencing the Container, one referencing the RootEntity (both perfectly alright, as I suppose), and finally one referencing the own PK having the usual Hibernate-crypted name.
Using Hibernate Annotations 3.4.0.GA will not create the schema due to a
foreign key circularity dependency. My Hibernate Tools installation with Annotations 3.3.0GA does not care about this dependency and creates the schema. So, I downgraded the Hibernate Annotations Jar in the application to 3.3.0.GA and the schema creation works well. When running the application persisting an entity fails with the first attempt due to a constraint violation. Responsible is the third FK named above.
It seems to be independent of the concrete sub-classes of, e.g. EntityA. Even without them the FK is generated.
Now, my questions:
1. Where does this mentioned third FK come from? I can't figure out.
2. Why is it generated anyway?
3. Is there a way to prevent this FK from being generated?
4. Since I tried a lot of stuff, does anyone know if the general idea of the mixed inheritance strategies is actually possible with Annotations?
5. Does the second @Inheritance annotation override the previous for the concrete sub-classes?
Any help very appreciated!
Thanks already!
CU
Froestel