Having a class hierarchy like so
{code:title=AbstractEntity.java|borderStyle=solid} import java.io.Serializable; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.MappedSuperclass;
@MappedSuperclass public abstract class AbstractEntity implements Serializable {
@ManyToOne(optional = false) @JoinColumn(name = "ref_id", referencedColumnName = "id", nullable = false) private ReferencedEntity realm;
protected AbstractEntity() { }
public ReferencedEntity getRef() { return ref; }
public void setRef(final ReferencedEntity ref) { this.ref = ref; } } {code}
{code:title=ReferencedEntity.java|borderStyle=solid} import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.Id;
@Entity public abstract class ReferencedEntity implements Serializable { @Id private int id;
public ReferencedEntity() { super(); }
public int getId() { return id; } public int setId(int id) { this.id = id; } } {code}
{code:title=ConcreteEntity.java|borderStyle=solid} import java.io.Serializable; import javax.persistence.AssociationOverride; import javax.persistence.AssociationOverrides; import javax.persistence.Entity; import javax.persistence.ForeignKey; import javax.persistence.Id; import javax.persistence.JoinColumn;
@Entity @AssociationOverrides({ @AssociationOverride(name = "ref", joinColumns = @JoinColumn(name = "ref_id"), foreignKey = @ForeignKey(name = "FK_CONCRETEENT_REF")) }) public abstract class ConcreteEntity implements Serializable { @Id private int id;
public ConcreteEntity() { super(); }
public int getId() { return id; } public int setId(int id) { this.id = id; } } {code}
{code:title=persistence.xml|borderStyle=solid} <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="modelBase" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <!- ... -> <properties> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/coyapp?useUnicode=true&useJDBCCompliantTimezoneS‌​hift=true&useLegacyDatetimeCode=false&serverTimezone=UTC" /> <property name="javax.persistence.jdbc.user" value="root" /> <property name="javax.persistence.jdbc.password" value="root" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.hbm2ddl.auto" value="create-drop" /> <!--<property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/> <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:testdb"/> <property name="javax.persistence.jdbc.user" value="sa"/> <property name="javax.persistence.jdbc.password" value=""/> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="update"/>--> </properties> </persistence-unit> </persistence> {code}
The overridden foreign key for the AbstractEntity#ref property is never applied and hibernate will use the default foreign key for all derived entity classes.
Having debugged a little bit, it seems that overriding foreign key names is not yet supported as overriding for example nullable does work.
Since I have a rather large number of entities for my next project that all derive from the same mapped superclass, not having this feature is quite a bummer as I now must refactor all such associations into the concrete entity classes. And these are quite a lot. |
|