在这个问题中,我正在使用Hibernate 4.3.4。最终和SpringORM 4.1.2。释放。
我有一个User类,它包含这样的一组Card实例:
@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添加到cards集合并保存实体,则一切正常。但是,如果我向集合中添加AbilityCardInstance并保存实体,它将与组织一起失败。冬眠错误类异常。我在帖子的底部添加了确切的异常消息。
我通读了一些问题,在处理基类集合时,延迟加载似乎是一个问题,因此,在添加卡片并保存之前,我是如何加载用户实体的:
User user = this.entityManager.createQuery("FROM User u " +
"WHERE u.id = ?1", User.class)
.setParameter(1, id)
.getSingleResult();
Hibernate.initialize(user.getCards());
return user;
org.hibernate.WrongClassException: Object [id=1] was not of the specified subclass [org.gwentonline.model.cards.UnitCard] : Discriminator: leader
提前感谢您提供有关如何解决此问题的任何线索。如果您需要更多信息,我很乐意更新我的问题!
我解决了这个问题。
根本原因在于这种设计:
@Table
@Entity
@Inheritance
@DiscriminatorColumn(name = "card_type", discriminatorType = DiscriminatorType.STRING)
public class CardInstance<T extends Card> {
protected T card;
}
@Entity
@DiscriminatorValue("leader")
public class LeaderCardInstance extends CardInstance<LeaderCard> {
}
java中没有关于类的泛型类型的运行时信息。有关更多信息,请参阅此问题:Java泛型-类型擦除-发生的时间和内容
这意味着hibernate无法确定CardInstance
类的实际类型。
解决方案是简单地摆脱泛型类型和所有扩展(实现)类,只使用一个这样的类:
@Table
@Entity
@Inheritance
@DiscriminatorColumn(name = "card_type", discriminatorType = DiscriminatorType.STRING)
public class CardInstance {
Card card;
}
这是可能的(顺便说一句,更好的设计),因为成员卡
携带有关卡类型的所有信息。
我希望这能帮助那些遇到同样问题的人。
根据@ManyToOne
的JavaDocs第一段:
通常不需要显式指定目标实体,因为它通常可以从被引用的对象的类型中推断出来。
但是,在这种情况下,@ManyToOne
位于类型为泛型的字段上,泛型类型信息在编译类型时被擦除。因此,在反序列化时,Hibernate不知道字段的确切类型。
修复方法是将Target etEntity=Card.class
添加到@ManyToOne
。由于Card
是抽象的
并且具有@继承
和@判别列
注释,这会强制Hibernate通过所有可能的方式解析实际的字段类型。它使用Card
表的鉴别器值来执行此操作并生成正确的类实例。此外,类型安全保留在Java代码中。
因此,一般来说,每当有可能在运行时无法完全了解字段的类型时,请将targetEntity与manytone和OneToMany一起使用。
问题: 我是否需要删除接口IAbstractUserService上的泛型? 是否与此答案的类型擦除有关?https://stackoverflow.com/a/31266152/6698175 问题: 我得到了这个例外: <代码>组织。冬眠ErrorClassException:对象[id=1]不属于指定的子类[com.faz.idb.models.advisor]:加载的对象属于错误的com类
我正在尝试将值更新到表中。如果新创建和保存的日期范围id工作正常。但是当试图更新现有日期范围id的值时,它会给我一个错误“org”。冬眠TransientObjectException:对象引用未保存的临时实例-在刷新之前保存临时实例:'。如何更新两种情况下的表值?
我试图在名为Person和Address的两个实体之间建立单向关系,同时保存Person(包含地址集合)获取组织。冬眠TransientObjectException:对象引用未保存的临时实例。 当我更改cascadeType=all时,子对象正在传播。但这里的问题是cascadeType=all Hibernate在删除所属实体时也会尝试删除子实体。我不希望发生这种情况,因为在很多关系中,子实体
我在Hibernate中使用注释。我得到这个错误: 组织。冬眠MappingException:未知实体:xyz。豆在组织进行测试。冬眠实施。SessionFactoryImpl。位于org的getEntityPersister(SessionFactoryImpl.java:550)。冬眠事件def。DefaultLoadEventListener。org上的onLoad(DefaultLoad
初始数据。专业有很多科目。 专业JAVA 对于一个主题来说,专业不能为空。我希望它能以下一种方式工作:当我保存/更新/分离一个主题时,同样的操作必须应用于专业。当我删除一个主题时,专业不会发生任何变化。 主题JAVA 我写了一个集成测试。生成专业()和生成主题()这只是util方法。 你可以在这张图片上看到测试结果。 subjectService在此处引发了异常。保存(主题1); 原因:org。冬
我正在将一个应用程序从Spring 3迁移到Spring 4。特别是,我正在将其迁移到 这是与Spring 3一起使用的原始代码: 在Spring 4中,我将其更新为: 方法中的每一行都成功,并且返回行的结果不为空。但是,当方法退出时会发生异常: org.springframework.transaction.TransactionSystemException:无法提交Hibernate事务;嵌