In this question I am working with Hibernate 4.3.4.Final and Spring ORM 4.1.2.RELEASE.
I have an User class, that holds a Set of CardInstances like this:
@Entity
@Table
public class User implements UserDetails {
protected List<CardInstance> cards;
@ManyToMany
public List<CardInstance> getCards() {
return cards;
}
// setter and other members/methods omitted
}
@Table
@Entity
@Inheritance
@DiscriminatorColumn(name = "card_type", discriminatorType = DiscriminatorType.STRING)
public abstract class CardInstance<T extends Card> {
private T card;
@ManyToOne
public T getCard() {
return card;
}
}
@Table
@Entity
@Inheritance
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(name = "card_type", discriminatorType = DiscriminatorType.STRING)
public abstract class Card {
// nothing interesting here
}
I have several types of cards, each extending the Card base class and the CardInstance base class respectivly like this:
@Entity
@DiscriminatorValue("unit")
public class UnitCardInstance extends CardInstance<UnitCard> {
// all types of CardInstances extend only the CardInstance<T> class
}
@Entity
@DiscriminatorValue("leader")
public class LeaderCardInstance extends CardInstance<LeaderCard> {
}
@Entity
@DiscriminatorValue("unit")
public class UnitCard extends Card {
}
@Entity
@DiscriminatorValue("leader")
public class LeaderCard extends AbilityCard {
}
@Entity
@DiscriminatorValue("hero")
public class HeroCard extends UnitCard {
// card classes (you could call them the definitions of cards) can
// extend other types of cards, not only the base class
}
@Entity
@DiscriminatorValue("ability")
public class AbilityCard extends Card {
}
If I add a UnitCardInstance or a HeroCardInstance to the cards collection and save the entity everything works fine. But if I add a AbilityCardInstance to the collection and save the entity it fails with a org.hibernate.WrongClassException. I added the exact exception + message at the bottom of the post.
I read through some questions, and lazy loading seems to be a problem while working with collections of a base class, so here is how I load the User entity before adding the card and saving it:
User user = this.entityManager.createQuery("FROM User u " +
"WHERE u.id = ?1", User.class)
.setParameter(1, id)
.getSingleResult();
Hibernate.initialize(user.getCards());
return user;
The database entries for "cards"
The database entries for "cardinstances"
org.hibernate.WrongClassException: Object [id=1] was not of the specified subclass [org.gwentonline.model.cards.UnitCard] : Discriminator: leader
Thanks in advance for any clues how to fix this problem. If you need additional information I will gladly update my question!
User
withid=1
has aUnitCardInstance
withid=1
which holds a reference to aCard
withdiscriminator=leader
instead ofdiscriminator=unit
(becauseUnitCardInstance
s can only referenceUnitCard
s). Check yourcard_type
table forid=1
to see whatcard_id
it refers to and then check the discriminator value for that row. – Plantagenet@DiscriminatorValue("unit") public class UnitCardInstance
and@DiscriminatorValue("unit") public class UnitCard
. There is no reference to a discriminator value ofleader
in your post. This is why I mentioned that there is a mismatch between the JPA configuration and what Hibernate found in the database. – PlantagenetUnitCard
instance, which requires a discriminator value ofunit
according to your post; but the actual database row has the valueleader
so Hibernate cannot make the conversion. This is why I suggested that you check the data as well. – Plantagenetleader
and is expected, there may be some JPA misconfiguration somewhere. Do you haveLeaderCard
andLeaderCardInstance
classes? Are they correctly annotated with the discriminator valueleader
? – Plantagenet