2010-04-09 2 views
1

Я получаю эту ошибку гибернации:Hibernate MappingException

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 
    { 

    .... 

Update: Этот код генерируется HyperJaxB. Поэтому я не утверждаю, что все это понимаю, просто пытаюсь внести в него некоторые изменения!


Update2: Вот full (да ну это большой) файл исходного кода

ответ

2

Использование статического вложенного класса в качестве типа поля в порядке и поддерживается. Но Hibernate не будет знать, как сопоставить такой сложный тип с типом столбца (о чем говорится в сообщении об ошибке). Итак, вам нужно либо создать пользовательский тип для обработки этого, либо комментировать поле Results.BusinessDate с аннотацией @OneToOne, чтобы сохранить его в другой таблице (я также удалю , который бесполезен, но здесь это не проблема).

Update: Просто для уточнения, используя пользовательский тип или отображение сложного типа с @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, поля являются постоянными по умолчанию):

Update: Вы не можете смешивать поле и доступ к собственности. Таким образом, вы должны аннотировать getBusinessDate() с @Transient здесь. Извините, я не мог догадаться, что из показанного кода я думал, что это будет очевидно.

+0

Почему Hibernate даже заботится о поле «Results.BusinessDate» ('businessDate')? Он не аннотируется аннотацией Hibernate/JPA (только JAXB). Обратите внимание: если я удалю аннотации Hibernate/JPA из фактического внутреннего класса, я получаю ту же ошибку. –

+0

Я попробовал '@ OneToOne', не работал печально. –

+0

@Marcus вижу мое обновление. –

0

Те же замечания, Кевин Кроуэлла. Вы также можете не использовать внутренние классы для типов сущностей. Я на самом деле никогда не видел, чтобы кто-то делал это с Hibernate, поэтому я не уверен, возможно ли это, или как вы его наберете.

Аннотации @Inheritance на внутреннем классе BusinessDate также кажутся немного подозрительными - внутренний класс является статическим и не наследуется от другого объекта, если Hibernate не рассматривает внутренние классы как «унаследованные».

В целом, не совсем уверен, чего вы пытаетесь достичь, но вы можете сделать вашу жизнь труднее, чем должно быть. Я бы рекомендовал не использовать внутренние классы и просто сопоставлять все объекты более простым/простым способом.

+0

Из документации (http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html): «(...) Вы можете сохранить любой * статический * внутренний класс. Вы должны указать имя класса, используя стандартную форму, т.е. 'eg.Foo $ Bar'." –

+0

Достаточно честный. Я бы лично просто держался подальше от этого.Предполагается, что спящий режим сделает вашу жизнь проще, и я обнаружил, что делать (то, что я считаю) «неясными» вещами, просто дает вам массу проблем. –

+1

Нет ничего скрытого и неправильного ИМХО. Имеются допустимые варианты использования * статических вложенных классов * (которые вы МОЖЕТЕ создать извне). –

Смежные вопросы