java-通过Hibernate保存实体时org.hibernate.WrongClassException
作者:互联网
在这个问题中,我正在使用Hibernate 4.3.4.Final和Spring ORM 4.1.2.RELEASE.
我有一个User类,它拥有如下的CardInstances集:
@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
}
我有几种类型的卡,每种类型分别扩展了Card基类和CardInstance基类,如下所示:
@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 {
}
如果我将UnitCardInstance或HeroCardInstance添加到纸牌集合并保存实体,则一切正常.
但是,如果我将AbilityCardInstance添加到集合中并保存该实体,它将失败,并出现org.hibernate.WrongClassException.我在帖子底部添加了确切的异常消息.
我通读了一些问题,在处理基类的集合时,延迟加载似乎是一个问题,因此这是我在添加卡并保存之前加载User实体的方式:
User user = this.entityManager.createQuery("FROM User u " +
"WHERE u.id = ?1", User.class)
.setParameter(1, id)
.getSingleResult();
Hibernate.initialize(user.getCards());
return user;
“卡片”的数据库条目
“ cardinstances”的数据库条目
org.hibernate.WrongClassException: Object [id=1] was not of the specified subclass [org.gwentonline.model.cards.UnitCard] : Discriminator: leader
在此先感谢您提供任何线索来解决此问题.如果您需要其他信息,我们将很乐意更新我的问题!
解决方法:
根据first paragraph of the JavaDocs for @ManyToOne
:
It is not normally necessary to specify the target entity explicitly since it can usually be inferred from the type of the object being referenced.
但是,在这种情况下,@ ManyToOne位于类型为泛型的字段上,并且泛型类型信息在编译类型时被擦除.因此,在反序列化时,Hibernate不知道该字段的确切类型.
解决方法是将targetEntity = Card.class添加到@ManyToOne.由于Card是抽象的,并且具有@Inheritance和@DiscriminatorColumn批注,因此这迫使Hibernate通过所有可能的方式解析实际的字段类型.它使用Card表的鉴别值执行此操作,并生成正确的类实例.此外,Java代码中保留了类型安全性.
因此,通常,只要在运行时可能无法完全了解字段的类型,就可以将targetEntity与@ManyToOne和@OneToMany一起使用.
标签:java,spring,jpa,hibernate,spring-orm 来源: https://codeday.me/bug/20191012/1898101.html