Note: I think I solved it. I just need confirmation. Please see second post.
I have a parent/child situation I can't get working.
I have Country (parent) which contains cities (children).
These are my mappings:
Code:
<class name="data.Country" table="countries">
<id name="id" column="id" length="31">
<generator class="assigned" />
</id>
<set name="cities" table="cities" inverse="true" cascade="all-delete-orphan">
<key column="country" />
<one-to-many class="data.City" />
</set>
</class>
Code:
<class name="data.City" table="cities">
<id name="id" column="id" length="31">
<generator class="assigned" />
</id>
<many-to-one name="country" class="data.Country" column="country" />
</class>
And these are the java classes:
Note they extend Data.
Code:
public class Country extends Data
{
private Set<City> cities = new HashSet<City>(0);
/* Constructors */
public Country(String id)
{
setId(IdCounter.getInstance().getCountryId());
}
/* Getters */
public Set<City> getCities()
{
return cities;
}
/* Setters */
public void setCities(Set<City> cities)
{
this.cities = cities;
}
/* Override */
public boolean equals(Object o)
{
if (o instanceof Country)
return ((Country) o).getId().equals(id);
else
return false;
}
}
Code:
public class City extends Data
{
private Country country;
/* Constructors */
public City(Country country)
{
setId(IdCounter.getInstance().getCityId());
setCountry(country);
}
/* Getters */
public Country getCountry()
{
return country;
}
/* Setters */
public void setCountry(Country country)
{
this.country = country;
}
/* Override */
public boolean equals(Object o)
{
if (o instanceof City)
return ((City) o).getId().equals(id);
else
return false;
}
}
Code:
public abstract class Data
{
protected String id;
/* Getters */
public String getId()
{
return id;
}
/* Setters */
protected void setId(String id)
{
this.id = id;
}
/* Override */
public abstract boolean equals(Object o);
public int hashCode()
{
return new HashCodeBuilder().append(id).toHashCode();
}
public String toString()
{
return id;
}
}
I use this code to test:
Code:
try
{
Criteria crit = session.createCriteria(City.class).add(Restrictions.eq("country", "Auke-yyyy-DDD-kk-mm-ss-SSS-0001"));
Logger.get().error("Testing: 1");
List<City> list = crit.list();
Logger.get().error("Testing: 2");
Country country = list.get(0).getCountry();
System.out.println(country.getId());
}
catch (Exception e)
{
e.printStackTrace();
}
And this is the error I get:
Quote:
ERROR - (HibernateMain.java:21) - Testing: 1
ERROR - (BasicPropertyAccessor.java:191) - IllegalArgumentException in class: data.Data, getter method of property: id
org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of data.Data.id
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:195)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:206)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3619)
at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:3335)
at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:204)
at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:241)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:430)
at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:110)
at org.hibernate.loader.Loader.bindPositionalParameters(Loader.java:1728)
at org.hibernate.loader.Loader.bindParameterValues(Loader.java:1699)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1589)
at org.hibernate.loader.Loader.doQuery(Loader.java:696)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.doList(Loader.java:2228)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2125)
at org.hibernate.loader.Loader.list(Loader.java:2120)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:118)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1596)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306)
at main.HibernateMain.main(HibernateMain.java:22)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:169)
... 19 more
As you can see the error starts at: List<City> list = crit.list();
Edit: if I don't use the abstract Data class and copy the code to country and city, the same error occurs, so the inheritance isn't a problem.