I have a superclass (annotated with the @MappedSuperclass strategy) and 2 persistable subclasses: SubClass1 and SubClass2. This superclass contains a map of objects of type "EmbeddedObject". The problem is that when I instantiate an entity of type SubClass1 and try to persist it, I get a the following error:
Referential integrity constraint violation: "FKN0P0Y5R3MEM881KR8U3HDHYGS: PUBLIC.EMBEDDEDOBJECTSMAP_TESTOBJECT_MAPPING FOREIGN KEY(EMBEDDEDOBJECTSMAP_SUPERCLASSID) REFERENCES PUBLIC.SUBCLASS2(SUPERCLASSID) (1)"; SQL statement: insert into EmbeddedObjectsMap_TestObject_mapping (EmbeddedObjectsMap_SuperClassID, embeddedObjectsMap_KEY, EmbeddedObject_id) values (?, ?, ?) [23506-200]
My understanding is that, by building the corresponding row in the join table, Hibernate looks for a "SubClass2" type entity (instead of SubClass1 type), for an unknown reason.
Hint: I noticed that, if I change entity declaration's order in the hibernat.cfg.xml file, swapping the 2 lines as follows:
Before:
<mapping class="fr.blablabla.testpersistingmapinmappedsuperclasscontext.SubClass1" />
<mapping class="fr.blablabla.testpersistingmapinmappedsuperclasscontext.SubClass2" />
After:
<mapping class="fr.blablabla.testpersistingmapinmappedsuperclasscontext.SubClass2" />
<mapping class="fr.blablabla.testpersistingmapinmappedsuperclasscontext.SubClass1" />
... the error proves to disappear (but persisting a "SubClass2" entity will fail of course).
Here is my code:
The superclass:
package fr.blablabla.testpersistingmapinmappedsuperclasscontext;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.MapKeyColumn;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
@MappedSuperclass
public class SuperClass {
public SuperClass() {
// TODO Auto-generated constructor stub
}
protected Long superClassID;
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
@Column(name = "SuperClassID")
public Long getSuperClassID() {
return superClassID;
}
public void setSuperClassID(final Long superClassID) {
this.superClassID = superClassID;
}
private Map<Long, EmbeddedObject> embeddedObjectsMap= new HashMap<Long, EmbeddedObject>();
@OneToMany (cascade = CascadeType.ALL)
@Fetch(FetchMode.JOIN)
@JoinTable(
name = "EmbeddedObjectsMap_TestObject_mapping",
joinColumns = {@JoinColumn(name = "EmbeddedObjectsMap_SuperClassID", referencedColumnName = "superClassID")},
inverseJoinColumns = {@JoinColumn(name = "EmbeddedObject_id", referencedColumnName = "embeddedObjectID")})
@MapKeyColumn
public Map<Long, EmbeddedObject> getEmbeddedObjectsMap() {
return (Map<Long, EmbeddedObject>) embeddedObjectsMap;
}
public void setEmbeddedObjectsMap(Map<Long, EmbeddedObject> embeddedObjectsMap) {
this.embeddedObjectsMap=embeddedObjectsMap;
}
}
The 2 subclasses Subclass1 and SubClass2 are identical:
package fr.blablabla.testpersistingmapinmappedsuperclasscontext;
import javax.persistence.Entity;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class SubClass1 extends SuperClass {
public SubClass1() {
// TODO Auto-generated constructor stub
}
}
The object embedded in the hashmap is just a standard entity:
package fr.blablabla.testpersistingmapinmappedsuperclasscontext;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class EmbeddedObject {
public EmbeddedObject() {
// TODO Auto-generated constructor stub
}
protected Long embeddedObjectID;
@Id
@GeneratedValue //(strategy = GenerationType.IDENTITY)
public Long getEmbeddedObjectID() {
return embeddedObjectID;
}
public void setEmbeddedObjectID(Long embeddedObjectID) {
this.embeddedObjectID = embeddedObjectID;
}
}
And finally, the main class:
package fr.blablabla.testpersistingmapinmappedsuperclasscontext;
import java.util.Map;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class TestPersistingMap {
public TestPersistingMap() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
SuperClass type1SubClass= new SubClass1();
Transaction transaction = null;
try (Session session = HibernateUtilTest.getSessionFactory().getCurrentSession()) {
// start a transaction
transaction = session.beginTransaction();
EmbeddedObject embeddedObject1 = new EmbeddedObject();
Map<Long, EmbeddedObject> map =type1SubClass.getEmbeddedObjectsMap();
map.put(1L, (EmbeddedObject) embeddedObject1);
session.saveOrUpdate(type1SubClass);
// commit transaction
transaction.commit();
System.out.println("entity persisted:"+ type1SubClass.toString());
} catch (Exception e) {
e.printStackTrace();
if (transaction != null) {
transaction.rollback();
}
}
System.out.println("Fin du programme TestpersistingMap");
}
}
Any help highly appreciated !