I'm trying to implement inheritance with a joined subclass strategy, while keeping track of the order of the list of combined entities.
I've got a SHOP table, with an ID and some metadata.
A SHOP has to maintain an ordered list of several types of entities, which have some metadata in common.
This is what I have at the moment in terms of entities and mappings:
@Entity
public class Shop extends PersistedEntity {
// Persistend entity is a common class that declares the @Id column as:
// @Id
// @GeneratedValue(strategy = GenerationType.AUTO)
// public int getId() {
// return this.id;
// }
// ... some generic fields
private List<ShopAssets> shopAssets = new ArrayList<ShopAssets>();
@ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
@JoinTable(name = "ShopAssets", joinColumns = { @JoinColumn(name = "shop_id") }, inverseJoinColumns = { @JoinColumn(name = "id") })
@OrderColumn(name="position")
public List<ShopAssets> getShopAssets() {
return shopAssets;
}
}
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "assetType")
public class ShopAsset extends PersistedEntity {
// Again, the id integer column is inherited from PersistedEntity
private Shop shop;
private int position;
private ShopFieldAsset keyAsset;
@ManyToOne
@JoinColumn(name = "shop_id")
public Shop getShop() {
return shop;
}
public int getPosition() {
return position;
}
@ManyToOne
@JoinColumn(name = "keyAsset_id")
public ShopFieldAsset getKeyAsset() {
return keyAsset;
}
// ... setters not included
}
@Entity
@DiscriminatorValue("field")
@PrimaryKeyJoinColumn(name = "id")
public class ShopFieldAsset extends ShopAsset {
// ... bunch of standard string properties
}
@Entity
@DiscriminatorValue("common")
@PrimaryKeyJoinColumn(name = "id")
public class ShopCommonAsset extends ShopAsset {
// ... bunch of standard string properties
}
@Entity
@DiscriminatorValue("expired")
@PrimaryKeyJoinColumn(name = "id")
public class ShopExpiredAsset extends ShopAsset {
// ... bunch of standard string properties
}
Database tables are as follows (grossly):
Shop: id(PK). name, location
ShopAsset: id(PK), shop_id, assetType, position, keyAsset_id(FK on ShopFieldAsset[id])
ShopFieldAsset: id(PK and also FK to ShopAsset[id]), name, type, other standard columns);
ShopCommonAsset: id(PK and also FK to ShopAsset[id]), name, type, other standard columns);
ShopExpiredAsset: id(PK and also FK to ShopAsset[id]), name, type, other standard columns);
All I'm trying to do in my test is to create a shop and persist it with a collection of assets, maintaining the order in which they were added to the shop.
What I'm getting is:
org.hibernate.MappingException: Foreign key (FK_ep3g3p25oddon8apvq8kgji6w:ShopFieldAsset [id])) must have same number of columns as the referenced primary key (ShopAsset [shop_id,position])
And I just don't get where that primary key definition comes from...
I realised that derived entities may be getting in the way (the fact that any ShopAsset has a foreign key on the ShopFieldAsset subclass...), but I'm stumped as to how I should be defining the mappings.
As if that wasn't enough, if/when I get that to work, is there a clever way to have getters on a Shop to retrieve a collection of assets of a specific type, e.g. getShopCommonAssets() ? I briefly looked into using @Where, but obviously I left that one the side until I get the basics going!
Any help greatly appreciated.