Hi all,
We're encountering some problems with polymorphic associations.
First of all where using hibernate version 3.2.1.
Overview of domain model (simplified version)
Code:
----------------------- -----------------------
| |* *| |
| PointOfSaleDo |----------->| AbstractLocationDo |
| | | |
----------------------- -----------------------
/ \
---
|
---------------------------------------------------------------
| | | |
| | | |
-------------- --------------- -------------- ------------
| |1 *| |1 *| |1 *| |
| WorldDo |<------| ContinentDo |<------| CountryDo |<------| CityDo |
| | | | | | | |
-------------- --------------- -------------- ------------
When using annotations if we retrieve a pointOfSaleDo object and then retrieve the AbstractLocationDo collection we get the following error:
Code:
org.hibernate.WrongClassException: Object with id: 4 was not of the specified subclass: com.....WorldDo (loaded object was of wrong class class com.....CityDo)
at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1234)
...
With the "old school" Hibernate mapping files everything works a expected. A collection of locations is retrieved with multiple locations of a different type.
Also when
using annotations if we try to retrieve a CityDo location we get the following error
(which we don't get when using mapping files):
Code:
SEVERE: IllegalArgumentException in class: com.....StateDo, setter method of property: country
27-sep-2007 14:00:42 org.hibernate.property.BasicPropertyAccessor$BasicSetter set
SEVERE: expected type: com..CountryDo, actual value: com....WorldDo
27-sep-2007 14:00:42 org.hibernate.event.def.DefaultLoadEventListener onLoad
INFO: Error performing load command
org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of com..StateDo.country
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:104)
Below i'v copied some snippets from the annotation configurationPointOfSaleDoCode:
/**
*
* The Point Of Sale class.
*/
@Entity
@Table(name = "Point_Of_Sale")
public class PointOfSaleDo implements DataObject {
<< some fields >>
/**
* The collection of allowed origin locations
*/
private Set<AbstractLocationDo> allowedOrigins;
/**
* @return List
*/
@ManyToMany(targetEntity = AbstractLocationDo.class, cascade = {CascadeType.ALL })
@JoinTable(name = "ALLOWED_ORIGINS", joinColumns = {@JoinColumn(name = "POINT_OF_SALE_ID") }, inverseJoinColumns = {@JoinColumn(name = "LOCATION_ID") })
public Set<AbstractLocationDo> getAllowedOrigins() {
return allowedOrigins;
}
/**
* @param allowedOrigins The collection of allowed origin locations
*/
public void setAllowedOrigins(Set<AbstractLocationDo> allowedOrigins) {
this.allowedOrigins = allowedOrigins;
}
}
AbstractLocationDo Code:
@Entity
@Table(name = "Location", uniqueConstraints = {@UniqueConstraint(columnNames = {"LOCATION_CODE", "LOCATION_TYPE" }) })
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name = "LOCATION_TYPE",
discriminatorType = DiscriminatorType.STRING, length = 10
)
public abstract class AbstractLocationDo implements DataObject {
<< some field >>
}
CityDoCode:
@Entity
@DiscriminatorValue("City")
@ForceDiscriminator
public class CityDo extends AbstractStationDo {
private CountryDo country;
private Set<AirportDo> airports;
/**
*
* Get airports
*
* @return Set
*/
@OneToMany(mappedBy = "city", cascade = {CascadeType.PERSIST, CascadeType.MERGE })
public Set<AirportDo> getAirports() {
return airports;
}
/**
*
* Get country
*
* @return Country
*/
@ManyToOne
@JoinColumn(name = "LOCATED_IN_ID")
public CountryDo getCountry() {
return country;
}
<< rest of getters and setters>>
}
Did we do something wrong in the annotations or is there a bug in the annotation processor from hibernate?
Thanks,
Lennard