【问题标题】:Hibernate MappingException休眠映射异常
【发布时间】:2010-04-09 22:17:43
【问题描述】:

我收到了这个休眠错误:

org.hibernate.MappingException: Could not determine type for: 
a.b.c.Results$BusinessDate, for columns: [org.hibernate.mapping.Column(businessDate)]

课程如下。有谁知道我为什么会收到这个错误?

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "businessDate"
})
@XmlRootElement(name = "Results")
@Entity(name = "Results")
@Table(name = "RESULT")
@Inheritance(strategy = InheritanceType.JOINED)
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Results implements Equals, HashCode
{

    @XmlElement(name = "BusinessDate", required = true)
    protected Results.BusinessDate businessDate;

    public Results.BusinessDate getBusinessDate() {
        return businessDate;
    }

    public void setBusinessDate(Results.BusinessDate value) {
        this.businessDate = value;
    }

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "raw",
        "display"
    })
    @Entity(name = "Results$BusinessDate")
    @Table(name = "BUSINESSDATE")
    @Inheritance(strategy = InheritanceType.JOINED)
    public static class BusinessDate implements Equals, HashCode
    {

    ....

更新:此代码由HyperJaxB 生成。所以我并没有声称自己了解全部,只是试图对其进行一些更改!


Update2:这是full(是的,它很大)src 文件

【问题讨论】:

    标签: java hibernate orm mappingexception


    【解决方案1】:

    使用静态嵌套类作为字段类型很好并受支持。但是 Hibernate 不知道如何将如此复杂的类型映射到列类型(这是错误消息所说的)。 因此,您需要创建一个用户类型来处理此问题,或者使用 @OneToOne 批注注释 Results.BusinessDate 字段以将其保留在另一个表中(我还将删除无用的 @Inheritance 但这不是问题在这里)。

    更新:澄清一下,使用用户类型或将复杂类型映射到@OneToOne 确实有效。以下代码完美运行(经过测试):

    @Entity
    public class EntityWithStaticNestedClass implements Serializable {
        @Id
        @GeneratedValue
        private Long id;
    
        @OneToOne
        private EntityWithStaticNestedClass.StaticNestedClass nested;
    
        public Long getId() { return id; }
    
        public void setId(Long id) { this.id = id; }
    
        public EntityWithStaticNestedClass.StaticNestedClass getNested() { 
            return nested;
        }
    
        public void setNested(EntityWithStaticNestedClass.StaticNestedClass nested) {
            this.nested = nested;
        }
    
        @Entity
        public static class StaticNestedClass implements Serializable {
            @Id
            @GeneratedValue
            private Long id;
    
            public Long getId() { return id; }
    
            public void setId(Long id) { this.id = id; }
        }
    }
    

    两个实体都很好地保存在各自的表中。但是你没有显示完整的代码,也没有显示确切的错误,所以我不能说为什么它不适合你(也许你错过了@Id 等)。

    话虽如此,如果您根本不希望 businessDate 持久化,请使用 @Transient 对其进行注释(使用 JPA,字段默认为持久化):

    更新:您不能混合使用字段和属性访问权限。所以你需要在这里用@Transient注释getBusinessDate()。抱歉,我无法从显示的代码中猜到这一点,我认为这很明显。

    【讨论】:

    • 为什么 Hibernate 还要关心 Results.BusinessDate 字段 (businessDate)?它没有使用 Hibernate/JPA 注释进行注释(只有 JAXB 注释)。请注意,如果我从实际的内部类中删除 Hibernate/JPA 注释,我会得到相同的错误。
    • @Marcus 您很可能没有以正确的方式使用它。你能展示你的代码吗?
    • 我将发布代码.. 遗憾的是,这是由 HyperJaxB 生成的 2000 行文件!谢谢你的帮助..
    【解决方案2】:

    与凯文克劳威尔相同的评论。您可能还会考虑不将内部类用于实体类型。我实际上从未见过有人用 Hibernate 做到这一点,所以我不确定它是否可能,或者你将如何映射它。

    BusinessDate 内部类上的@Inheritance 注释似乎也有点可疑 - 内部类是静态的,并且不会从另一个实体继承,除非 Hibernate 将内部类视为“继承的”。

    总体而言,不太确定您想要完成什么,但您可能会让您的生活变得比应有的更艰难。我建议不要使用内部类,而只是以更简单/直接的方式映射所有实体。

    【讨论】:

    • 来自文档(docs.jboss.org/hibernate/core/3.3/reference/en/html/…):“(...)您可以保留任何 static 内部类。您应该使用标准形式指定类名,即。 eg.Foo$Bar。”
    • 很公平。不过,我个人会远离那个。 Hibernate 应该让你的生活更轻松,我发现做(我认为是)“晦涩”的事情只会给你带来很多问题。
    • 恕我直言,没有什么晦涩和错误的。 静态嵌套类(您可以从外部实例化)有一些有效的用例。
    猜你喜欢
    • 1970-01-01
    • 2016-02-05
    • 2016-10-18
    • 1970-01-01
    • 2015-03-04
    • 2019-06-10
    • 2017-01-22
    • 1970-01-01
    • 2016-01-20
    相关资源
    最近更新 更多