2016-09-15 5 views
1

я следующие классы (упрощенный):ClassCastException при использовании вложенного mappedBy с Hibernate

Адрес

Представляет географической зоны

@Entity 
@Table(name = "location") 
public class Location extends DomainObject { 

    @OneToMany(mappedBy = "lastPositionHistoric.location") 
    private Set<Thing> things = new LinkedHashSet<>(0); 

    public Location() { 
    } 

    public Set<Thing> getThings(){ 
     return things; 
    } 

    public void setThings(Set<Thing> things){ 
     this.things = things; 
    } 

} 

вещь

представляет движущийся актив

@Entity 
@Table(name = "thing") 
public class Thing extends DomainObject { 

    @OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.REFRESH}) 
    @JoinColumn(name = "last_position_thing_historic_id") 
    private ThingHistoric lastPositionHistoric; 

    public Thing() { 
    } 

    public ThingHistoric getLastPositionHistoric() { 
     return lastPositionHistoric; 
    } 

    public void setLastPositionHistoric(ThingHistoric lastPositionHistoric) { 
     this.lastPositionHistoric = lastPositionHistoric; 
    } 

} 

ThingHistoric

Представляет историю GPS вещи (я удалил unrelevant свойства GPS для задачи)

@Entity 
@Table(name = "thing_historic") 
public class ThingHistoric extends DomainObject { 

    @ManyToOne(cascade = {CascadeType.REFRESH, CascadeType.MERGE}, fetch = FetchType.EAGER) 
    @JoinColumn(name = "thing_id", nullable = false) 
    @NotNull 
    private Thing thing; 

    @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.REFRESH}) 
    @JoinColumn(name = "location_id") 
    private Location location; 

    public ThingHistoric() { 

    } 

    public Thing getThing() { 
     return thing; 
    } 

    public ThingHistoric setThing(Thing thing) { 
     this.thing = thing; 
     return this; 
    } 

    public Location getLocation() { 
     return location; 
    } 

    public ThingHistoric setLocation(Location location) { 
     this.location = location; 
     return this; 
    } 
} 

Объяснение

Каждая вещь движется в реальном мире, и может быть в данный время внутри места или в любом месте.

Когда Вещь находится внутри местоположения, объект lastPositionHistoric имеет свое значение местоположения, равное местоположению, внутри которого находится предмет.

Вопрос

Когда я добавил вещей поля внутри Расположение класса, Hibernate начал жаловаться со следующей ошибкой:

Caused by: java.lang.ClassCastException: org.hibernate.mapping.ManyToOne cannot be cast to org.hibernate.mapping.Component 
    at org.hibernate.mapping.PersistentClass.getRecursiveProperty(PersistentClass.java:465) 
    at org.hibernate.mapping.PersistentClass.getRecursiveProperty(PersistentClass.java:421) 
    at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:763) 
    at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:724) 
    at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:54) 
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1621) 
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1589) 
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) 
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:848) 
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:876) 
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) 
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) 
    ... 52 more 

Я не понимаю, почему из-за отображение Кажется правильным для меня. Перечень вещей внутри местоположения должен быть всем, что имеет lastPositionHisotric.location, равное данному местоположению, не так ли?

Является ли это ошибкой или мое сопоставление определенно не так?

ответ

2

"." (точка) в mappedBy относится к полям внутри встроенных атрибутов (см., например, спецификацию JPA 11.1.4.1). Он не предназначен для использования с сущностями! И я не вижу ничего встроенного в ваши сопоставления. Так что да ваше отображение определенно неправильно

Точка («») синтаксис обозначения должны быть использованы в элементе mappedBy для указать атрибут отношения внутри вложенного атрибута. Значение каждого идентификатора, используемого с точечной нотацией, - это имя соответствующего встроенного поля или свойства .

+0

О, я пропустил этот момент, благодарю за указание на это! Будет ли другой способ иметь возможность отображать список вещей из местоположения? – singe3

+0

Единственное, что связано с mappedBy, - это связать 2 непосредственно связанных поля, чтобы они были двунаправленными. С вашими текущими отношениями (без mappedBy) вы все равно можете перемещаться между различными объектами, поэтому не видите проблемы. –

+0

Я не могу перемещаться из местоположения в объекты с этим сопоставлением. Чтобы решить эту проблему, я добавил копию текущего идентификатора местоположения непосредственно в таблицу вещей. Я отмечаю ваш ответ как принятый, потому что это помогло мне переосмыслить то, что я делаю. – singe3

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